#!/bin/bash

# Hardware Configuration Reader for rpi-control-hat
# Source this file in other scripts to access hardware mappings
# Usage: source config/hardware-reader.sh

# Determine hardware config location
if [ -f "$(dirname "${BASH_SOURCE[0]}")/hardware.conf" ]; then
    # Development installation or when sourced from config directory
    HARDWARE_CONFIG="$(dirname "${BASH_SOURCE[0]}")/hardware.conf"
else
    # Package installation
    # Use installed config file by default, fall back to development config
    if [ -f "/etc/rpi-power-hat/hardware.conf" ]; then
        HARDWARE_CONFIG="/etc/rpi-power-hat/hardware.conf"
    elif [ -f "$(dirname "$0")/../../init/config/hardware.conf" ]; then
        HARDWARE_CONFIG="$(dirname "$0")/../../init/config/hardware.conf"
    else
        echo "Error: Could not find hardware.conf configuration file"
        exit 1
    fi
fi

# Function to read hardware configuration values
get_hardware_config_deprecated() {
    local section="$1"
    local key="$2"
    local config_file="${3:-$HARDWARE_CONFIG}"
    
    if [[ ! -f "$config_file" ]]; then
        echo "Error: Hardware config file $config_file not found" >&2
        return 1
    fi
    
    # Use awk to parse INI-style config file
    awk -F= -v section="[$section]" -v key="$key" '
        $0 == section { in_section = 1; next }
        /^\[/ { in_section = 0; next }
        in_section && $1 ~ "^[ \t]*"key"[ \t]*$" { gsub(/^[ \t]+|[ \t]+$/, "", $2); print $2; exit }
    ' "$config_file"
}

find_hwmon_by_phandle() {
    local phandle="$1"

    for hwmon in /sys/class/hwmon/hwmon*; do
        cmp --quiet "$phandle" "$hwmon/of_node/phandle" && echo -n "$hwmon" && return 0
    done

    echo "Error: Could not find hwmon" >&2
    return 1
}

find_gpiochip_by_port() {
    local port="$1"

    local info=$(gpioinfo ${port}_PWR 2>/dev/null) && echo ${info%% *} && return 0

    echo "Error: Could not find gpiochip" >&2
    return 1
}

get_hardware_config() {
    local port="$1"
    local key="$2"
    local config_file="${3:-$HARDWARE_CONFIG}"

    if [ "$port" = "DEFAULT" ]; then
        get_hardware_config_deprecated "$port" "$key" "$config_file"
        return
    fi

    # Port one of B1, B2, T1, T2
    local lower_port="${port,,}"
    local dt_entry="/proc/device-tree/rpi-power-hat-${lower_port:0:1}"

    local connector="${lower_port:1:1}"

    case "$key" in
        "current_hwmon")
            local phandle="${dt_entry}/power${connector}-monitor"
            find_hwmon_by_phandle "$phandle"
            echo "/curr1_input"
            ;;
        "power_hwmon")
            local phandle="${dt_entry}/power${connector}-monitor"
            find_hwmon_by_phandle "$phandle"
            echo "/power1_input"
            ;;
        "gpiochip")
            find_gpiochip_by_port "$port"
            ;;
        *)
            get_hardware_config_deprecated "$port" "$key" "$config_file"
            ;;
    esac
}

# Port-specific hardware mapping functions
get_current_hwmon_path() {
    local port="$1"
    local path=$(get_hardware_config "$port" "current_hwmon")
    if [[ -z "$path" ]]; then
        path=$(get_hardware_config "DEFAULT" "current_hwmon")
    fi
    echo "$path"
}

get_power_hwmon_path() {
    local port="$1"
    local path=$(get_hardware_config "$port" "power_hwmon")
    if [[ -z "$path" ]]; then
        path=$(get_hardware_config "DEFAULT" "power_hwmon")
    fi
    echo "$path"
}

get_gpiochip() {
    local port="$1"
    local chip=$(get_hardware_config "$port" "gpiochip")
    if [[ -z "$chip" ]]; then
        chip=$(get_hardware_config "DEFAULT" "gpiochip")
    fi
    echo "$chip"
}

get_gpiopin() {
    local port="$1"
    local pin=$(get_hardware_config "$port" "gpiopin")
    if [[ -z "$pin" ]]; then
        pin=$(get_hardware_config "DEFAULT" "gpiopin")
    fi
    echo "$pin"
}

get_shutdown_threshold() {
    local device_type="$1"
    local threshold=$(get_hardware_config "$device_type" "shutdown_threshold")
    if [[ -z "$threshold" ]]; then
        threshold=$(get_hardware_config "DEFAULT" "shutdown_threshold")
    fi
    echo "$threshold"
}

# Get GPIO line name for libgpiod v2 format
get_gpio_line_name() {
    local port="$1"
    case "$port" in
        B1) echo "B1_PWR" ;;
        B2) echo "B2_PWR" ;;
        T1) echo "T1_PWR" ;;
        T2) echo "T2_PWR" ;;
        *) echo "" ;;
    esac
}

# Get boot GPIO line name for mass storage mode
get_boot_gpio_line_name() {
    local port="$1"
    case "$port" in
        B1) echo "B3" ;;
        B2) echo "B4" ;;
        T1) echo "T3" ;;
        T2) echo "T4" ;;
        *) echo "" ;;
    esac
}

# Validation function to check if port is valid
validate_port() {
    local port="$1"
    case "$port" in
        B1|B2|T1|T2) return 0 ;;
        *) return 1 ;;
    esac
}

# Function to list all available ports
list_ports() {
    echo "B1 B2 T1 T2"
}

# Function to list all device types  
list_device_types() {
    echo "pi5 pi4 pi0"
}
