# --- [Command-Line Parameter Support] ---
param (
    [Parameter()]
    [string]$COMPORT = "6"           # Default COM port for testing
)

# Force working directory to script location after elevation
Set-Location -Path $PSScriptRoot

# Validate COM port parameter
if (-not $COMPORT) {
    Write-Host "Missing COM port argument. Please call this script with a COM port, e.g. powershell.exe -File script.ps1 6"
    exit 1
}

Write-Host "Selected COM Port: $COMPORT" -ForegroundColor Yellow

### --- [Step 1] Initialize variables, log directory paths, and file names ---

# Customized serial numbers and Bus Prefix
# Expected FTDI serial number
$FTDI_TargetSerial = "FT8EBM6XA"
# Expected FTDI VID/PID
$FTDI_BusPrefix = "VID_0403+PID_6001"

$MFGTool_IF91X_Download_Path = (Get-Location).Path
# Write-Output "MFGTool Path: $MFGTool_IF91X_Download_Path"

# Obtain system time (format YYYYMMDDHHMMSS)
$timestamp = Get-Date -Format "yyyyMMddHHmmss"
# Write-Output "Timestamp: $timestamp"

# Read the content of UserScanInput.txt (two levels above the script)
# Write-Output "Folder File Content: $content"
$userInputPath = Join-Path -Path $PSScriptRoot -ChildPath "..\\..\\UserScanInput.txt"
if (-not (Test-Path $userInputPath)) {
    Write-Host "UserScanInput.txt not found: $userInputPath" -ForegroundColor Red
    exit 3
}
$content = Get-Content -Path $userInputPath -Raw

# Start recording the entire script output to a log file
# Get the path of the parent directory two levels up from the current working directory
$MiddlelogDir = Split-Path -Path $MFGTool_IF91X_Download_Path -Parent

# Combine the paths to get the final Logs directory path
$MiddlelogDir = Join-Path -Path $MiddlelogDir -ChildPath "Logs"
$logDir = Join-Path -Path $MiddlelogDir -ChildPath $content

# Replace the $(system time) part of the file name with $content
$Output_Txtfile = "${content}_btfw_download_process-if91x_results_${timestamp}.txt"
$StandardOutput_Txtfile = "btfw_download_process-if91x_results.txt"

# Check if the $content folder exists, and create it if not
$folderPath = Join-Path -Path $MiddlelogDir -ChildPath $content
if (-Not (Test-Path -Path $folderPath)) {
    Write-Host "Creating folder: $folderPath"
    New-Item -Path $folderPath -ItemType Directory | Out-Null
}

# Full path to the output file
$OutputFilePath = Join-Path -Path $logDir -ChildPath $Output_Txtfile

Write-Host "Resolved OutputFilePath: $OutputFilePath"
Write-Host "Resolved LogDir: $logDir"

# Check if the script has permissions to write to the file
if (-not (Test-Path -Path $OutputFilePath)) {
    try {
        New-Item -ItemType File -Path $OutputFilePath -Force | Out-Null
    } catch {
        Write-Host "Failed to create log file: $OutputFilePath" -ForegroundColor Red
        exit 4
    }
}

# Define a function to encapsulate Write-Log and log it.
function Write-Log {
    param (
        [string]$message
    )
    Write-Host $Message
    $Message | Out-File -FilePath $OutputFilePath -Append
}

Write-Log .

# Veda IF91x: Execute to download the Wi-Fi firmware
Write-Log "Veda IF91x : Execute to download the Bluetooth firmware"

# Function to check error and stop execution with timeout
function Check-Error {
    param([int]$ExitCode, [string]$Step = "")
    if ($ExitCode -ne 0) {
        Write-Log "Error encountered at step: $Step (ExitCode=$ExitCode)"
        Write-Log "Bluetooth Program failure ..."
        Copy-Item -Path $OutputFilePath -Destination (Join-Path $logDir $StandardOutput_Txtfile) -Force
        exit $ExitCode
    }
}


Write-Log "Please be patient for about 10 seconds for program BT firmware..."
Write-Log "...******************************..."
Write-Log "...*** DO NOT PRESS ANY KEY ! ***..."
Write-Log "...******************************..."
Write-Log ".."

### --- [Step 3] Scan and match FTDI device by serial and BusPrefix to obtain InstanceId ---

# --- Auto-correct COM port for Bluetooth (prefer COMX) ---

# Resolve FTDI COM port by VID/PID + Serial via Win32_SerialPort
function Resolve-BTComPort {
    param(
        [string]$VidPidPrefix,  # e.g. "VID_0403+PID_6001"
        [string]$TargetSerial   # e.g. "FT8FNBQUA"
    )
    try {
        # Convert "VID_0403+PID_6001" to a regex that can match both & and +, for example, "VID_0403.*PID_6001"
        $vidpidRegex = ($VidPidPrefix -replace '\+','.*')
        $rx = [regex]"$vidpidRegex.*$([regex]::Escape($TargetSerial))"

        # --- Plan A: Win32_SerialPort (Capture COMx directly) ---
        $ports = Get-CimInstance Win32_SerialPort -ErrorAction Stop | Where-Object {
            $_.PNPDeviceID -and $rx.IsMatch($_.PNPDeviceID)
        }
        if ($ports) {
            $best = $ports | Sort-Object {
                if ($_.DeviceID -match '^COM(\d+)$') { [int]$Matches[1] } else { 9999 }
            } | Select-Object -First 1
            if ($best -and $best.DeviceID -match '^COM(\d+)$') { return $Matches[1] }
        }

        # --- Plan B: Win32_PnPEntity 
        #             (Sometimes SerialPort cannot be captured, but there is Name: "USB Serial Port (COM6)") ---
        $pnps = Get-CimInstance Win32_PnPEntity -ErrorAction Stop | Where-Object {
            $_.PNPDeviceID -and $rx.IsMatch($_.PNPDeviceID) -and ($_.Name -match '\(COM\d+\)')
        }
        if ($pnps) {
            foreach ($n in $pnps) {
                if ($n.Name -match '\(COM(\d+)\)') { return $Matches[1] }
            }
        }

        # --- Plan C: Registry read FTDI PortName directly ---
        # HKLM:\SYSTEM\CurrentControlSet\Enum\FTDIBUS\VID_0403+PID_6001+FT8FNBQUA\0000\Device Parameters\PortName
        $regPath = "HKLM:\SYSTEM\CurrentControlSet\Enum\FTDIBUS\{0}+{1}\0000\Device Parameters" -f $VidPidPrefix, $TargetSerial
        if (Test-Path $regPath) {
            $port = (Get-ItemProperty -Path $regPath -Name 'PortName' -ErrorAction Stop).PortName
            if ($port -match '^COM(\d+)$') { return $Matches[1] }
        }
    } 
    catch {
        Write-Log ("Resolve-BTComPort error: {0}" -f $_.Exception.Message)
    }
    return $null
}

# Prefer VID/PID/SN detection; fallback: keep user COM if valid -> else Expected
$ExpectedBTCom = "1"

Write-Log ("Auto-detecting BT COM by VID/PID/SN (Prefix={0}, SN={1})..." -f $FTDI_BusPrefix, $FTDI_TargetSerial)
$detected = Resolve-BTComPort -VidPidPrefix $FTDI_BusPrefix -TargetSerial $FTDI_TargetSerial

    if ($detected) {
        $COMPORT = $detected
    Write-Log ("Detected FTDI via VID/PID/SN -> COM{0}" -f $COMPORT)
}
else {
    # Check if the COM given by the user exists; if it exists, respect it and do not overwrite it
    $userOk = $false
    try {
        $userOk = (Get-CimInstance Win32_SerialPort | Where-Object { $_.DeviceID -eq ("COM{0}" -f $COMPORT) }) -ne $null
    } catch { $userOk = $false }

    if ($userOk) {
        Write-Log ("VID/PID detection failed; keeping user-specified COM{0}" -f $COMPORT)
    } else {
        Write-Log ("VID/PID detection failed; falling back to COM{0}" -f $ExpectedBTCom)
        $COMPORT = $ExpectedBTCom
    }
}
Write-Log ("BT will use COM{0}" -f $COMPORT)

### --- [Step 3-1] Scan and match FTDI device by serial and BusPrefix to obtain InstanceId ---
# Get Hardware VIDs/PIDs of connected FTDI bus via devcon (optional verification)
$devcon = "devcon64.exe"
if (-not (Get-Command $devcon -ErrorAction SilentlyContinue)) {
    Write-Log "WARNING: devcon64.exe not found in PATH. FTDI verification skipped."
} else {
    $devconOutput = & $devcon hwids *FTDI* 2>$null
    $instanceId = $devconOutput | Where-Object { $_ -like "*$FTDI_BusPrefix+$FTDI_TargetSerial\0000" } | Select-Object -First 1

    if (-not $instanceId) {
        Write-Log ("FTDI device not found by devcon (Serial={0}, Prefix={1})." -f $FTDI_TargetSerial, $FTDI_BusPrefix)
        # We do not hard-fail here since COM was already resolved; uncomment to enforce:
        # Copy-Item -Path $OutputFilePath -Destination (Join-Path $logDir $StandardOutput_Txtfile) -Force
        # exit 5
    } else {
        Write-Log "Found FTDI device Instance ID:"
        Write-Log ("    {0}" -f $instanceId)
    }
}

### --- [Step 3] Run firmware program tool (MbtP.exe), with logging and error check ---

# Check if valid FTDI bus VID/PID were obtained
if (-not $instanceId) {
    Write-Log "Failed to obtain FTDI bus VID/PID."
    exit 1
}

Write-Log "..."
Write-Log ".. Bluetooth Firmware programming .."
$MbtPBat = Join-Path -Path $PSScriptRoot -ChildPath "..\\Files\\MbtP.exe"
#$HCDFile = Join-Path -Path $PSScriptRoot -ChildPath "..\\Files\\CYW55900A0_001.001.071.0147.0000_Generic_UART_37_4MHz_wlbga_iPA_sLNA_ANT0.hcd"
$HCDFile = Join-Path -Path $PSScriptRoot -ChildPath "..\\Files\\CYW55900A0_001.001.071.0154.0000_250115_TEST_ONLY.hcd"
$quotedHcd = "`"$HCDFile`""
$MbtPDir = Split-Path $MbtPBat -Parent

# Program via MbtP.exe tool with properly argument
Start-Process -FilePath $MbtPBat -ArgumentList @("download", "COM$COMPORT", $quotedHcd) -Wait -NoNewWindow -WorkingDirectory $MbtPDir -RedirectStandardOutput "$logDir\$Output_Txtfile"
$output_Program | Out-File -FilePath $OutputFilePath -Append
Check-Error

# Final success message
Write-Log "....."
Write-Log "Device programmed successfully ..."

### --- [Step 4] Finalize log output with standardized filename ---

# Copy Process Log with MAC as Standard naming format file
Copy-Item -Path $OutputFilePath -Destination (Join-Path $logDir $StandardOutput_Txtfile) -Force

Write-Log "Done."
