# deploy-sync-fixes.ps1
# Deploys patched Sync-FromNAS.ps1 and import.js to AD2 (192.168.0.6)
#
# Fixes deployed:
#   1. Sync-FromNAS.ps1 - PULL hang fix (temp file approach for large find output)
#   2. Sync-FromNAS.ps1 - SCP quoting fix (handles spaces, parens, special chars)
#   3. Sync-FromNAS.ps1 - Rename-OnNAS replaces Remove-FromNAS (.synced instead of delete)
#   4. import.js - INSERT OR REPLACE instead of INSERT OR IGNORE (re-tests keep latest)
#
# Run from: Mike's workstation (where the patched files live)
# Target: AD2 (192.168.0.6) as INTRANET\sysadmin

param(
    [switch]$DryRun  # Show what would be done without doing it
)

# ============================================================================
# Configuration
# ============================================================================
$AD2_IP = "192.168.0.6"
$AD2_USER = "INTRANET\sysadmin"
$AD2_PASSWORD = "Paper123!@#"

$SSH = "C:\Windows\System32\OpenSSH\ssh.exe"
$SCP = "C:\Windows\System32\OpenSSH\scp.exe"

# Source files (local to this machine)
$SCRIPT_DIR = Split-Path -Parent $MyInvocation.MyCommand.Path
$LOCAL_SYNC_SCRIPT = Join-Path $SCRIPT_DIR "Sync-FromNAS.ps1"
$LOCAL_IMPORT_SCRIPT = Join-Path $SCRIPT_DIR "import.js"

# Destination paths on AD2
$REMOTE_SYNC_PATH = "C:\Shares\test\scripts\Sync-FromNAS.ps1"
$REMOTE_IMPORT_PATH = "C:\Shares\testdatadb\database\import.js"
$REMOTE_SSH_DIR = "C:\Shares\test\scripts\.ssh"

$DATE_SUFFIX = Get-Date -Format "yyyyMMdd"

# ============================================================================
# Functions
# ============================================================================

function Write-Status {
    param(
        [string]$Marker,
        [string]$Message
    )
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    Write-Host "$timestamp [$Marker] $Message"
}

function Invoke-AD2Command {
    param([string]$Command)
    $result = & $SSH -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 "${AD2_USER}@${AD2_IP}" $Command 2>&1
    return $result
}

function Copy-ToAD2 {
    param(
        [string]$LocalPath,
        [string]$RemotePath
    )
    # SCP to AD2 - quote remote path for Windows paths with backslashes
    $result = & $SCP -O -o StrictHostKeyChecking=accept-new "$LocalPath" "${AD2_USER}@${AD2_IP}:`"${RemotePath}`"" 2>&1
    if ($LASTEXITCODE -ne 0) {
        $errorMsg = $result | Out-String
        Write-Status "ERROR" "SCP failed (exit $LASTEXITCODE): $errorMsg"
        return $false
    }
    return $true
}

# ============================================================================
# Pre-flight Checks
# ============================================================================

Write-Host ""
Write-Host "============================================"
Write-Host "  Dataforth Sync Fixes - Deployment Script"
Write-Host "============================================"
Write-Host ""

if ($DryRun) {
    Write-Status "INFO" "DRY RUN - no changes will be made"
    Write-Host ""
}

# Verify source files exist
Write-Status "INFO" "Checking source files..."

if (-not (Test-Path $LOCAL_SYNC_SCRIPT)) {
    Write-Status "ERROR" "Source file not found: $LOCAL_SYNC_SCRIPT"
    exit 1
}
Write-Status "OK" "Found: $LOCAL_SYNC_SCRIPT"

if (-not (Test-Path $LOCAL_IMPORT_SCRIPT)) {
    Write-Status "ERROR" "Source file not found: $LOCAL_IMPORT_SCRIPT"
    exit 1
}
Write-Status "OK" "Found: $LOCAL_IMPORT_SCRIPT"

# Verify AD2 is reachable
Write-Status "INFO" "Testing connectivity to AD2 ($AD2_IP)..."
$pingResult = Test-Connection -ComputerName $AD2_IP -Count 1 -Quiet
if (-not $pingResult) {
    Write-Status "ERROR" "Cannot reach AD2 at $AD2_IP"
    exit 1
}
Write-Status "OK" "AD2 is reachable"

# Test SSH connection
Write-Status "INFO" "Testing SSH connection..."
$sshTest = Invoke-AD2Command "echo CONNECTION_OK"
$sshTestStr = $sshTest | Out-String
if ($sshTestStr -notmatch "CONNECTION_OK") {
    Write-Status "ERROR" "SSH connection failed: $sshTestStr"
    exit 1
}
Write-Status "OK" "SSH connection established"

# ============================================================================
# Step 1: Create backups on AD2
# ============================================================================
Write-Host ""
Write-Status "INFO" "--- Step 1: Creating backups on AD2 ---"

if ($DryRun) {
    Write-Status "INFO" "[DRY RUN] Would backup $REMOTE_SYNC_PATH -> ${REMOTE_SYNC_PATH}.bak-${DATE_SUFFIX}"
    Write-Status "INFO" "[DRY RUN] Would backup $REMOTE_IMPORT_PATH -> ${REMOTE_IMPORT_PATH}.bak-${DATE_SUFFIX}"
} else {
    # Backup Sync-FromNAS.ps1
    $backupCmd1 = "copy `"$REMOTE_SYNC_PATH`" `"${REMOTE_SYNC_PATH}.bak-${DATE_SUFFIX}`""
    $backupResult1 = Invoke-AD2Command "cmd /c $backupCmd1"
    if ($LASTEXITCODE -eq 0) {
        Write-Status "OK" "Backed up Sync-FromNAS.ps1 -> .bak-${DATE_SUFFIX}"
    } else {
        Write-Status "WARNING" "Backup of Sync-FromNAS.ps1 may have failed (file might not exist yet): $($backupResult1 | Out-String)"
    }

    # Backup import.js
    $backupCmd2 = "copy `"$REMOTE_IMPORT_PATH`" `"${REMOTE_IMPORT_PATH}.bak-${DATE_SUFFIX}`""
    $backupResult2 = Invoke-AD2Command "cmd /c $backupCmd2"
    if ($LASTEXITCODE -eq 0) {
        Write-Status "OK" "Backed up import.js -> .bak-${DATE_SUFFIX}"
    } else {
        Write-Status "WARNING" "Backup of import.js may have failed (file might not exist yet): $($backupResult2 | Out-String)"
    }
}

# ============================================================================
# Step 2: Create .ssh directory on AD2 if missing
# ============================================================================
Write-Host ""
Write-Status "INFO" "--- Step 2: Ensuring .ssh directory exists ---"

if ($DryRun) {
    Write-Status "INFO" "[DRY RUN] Would create $REMOTE_SSH_DIR if missing"
} else {
    $mkdirCmd = "cmd /c if not exist `"$REMOTE_SSH_DIR`" mkdir `"$REMOTE_SSH_DIR`""
    Invoke-AD2Command $mkdirCmd | Out-Null
    Write-Status "OK" "Ensured .ssh directory exists: $REMOTE_SSH_DIR"

    # Create empty known_hosts if it does not exist
    $knownHostsPath = "$REMOTE_SSH_DIR\known_hosts"
    $touchCmd = "cmd /c if not exist `"$knownHostsPath`" type nul > `"$knownHostsPath`""
    Invoke-AD2Command $touchCmd | Out-Null
    Write-Status "OK" "Ensured known_hosts file exists: $knownHostsPath"
}

# ============================================================================
# Step 3: Deploy patched files
# ============================================================================
Write-Host ""
Write-Status "INFO" "--- Step 3: Deploying patched files ---"

if ($DryRun) {
    Write-Status "INFO" "[DRY RUN] Would SCP $LOCAL_SYNC_SCRIPT -> ${AD2_IP}:${REMOTE_SYNC_PATH}"
    Write-Status "INFO" "[DRY RUN] Would SCP $LOCAL_IMPORT_SCRIPT -> ${AD2_IP}:${REMOTE_IMPORT_PATH}"
} else {
    # Deploy Sync-FromNAS.ps1
    Write-Status "INFO" "Deploying Sync-FromNAS.ps1..."
    $success1 = Copy-ToAD2 -LocalPath $LOCAL_SYNC_SCRIPT -RemotePath $REMOTE_SYNC_PATH
    if ($success1) {
        Write-Status "OK" "Deployed Sync-FromNAS.ps1"
    } else {
        Write-Status "ERROR" "Failed to deploy Sync-FromNAS.ps1"
        exit 1
    }

    # Deploy import.js
    Write-Status "INFO" "Deploying import.js..."
    $success2 = Copy-ToAD2 -LocalPath $LOCAL_IMPORT_SCRIPT -RemotePath $REMOTE_IMPORT_PATH
    if ($success2) {
        Write-Status "OK" "Deployed import.js"
    } else {
        Write-Status "ERROR" "Failed to deploy import.js"
        exit 1
    }
}

# ============================================================================
# Step 4: Verify deployment
# ============================================================================
Write-Host ""
Write-Status "INFO" "--- Step 4: Verifying deployment ---"

if ($DryRun) {
    Write-Status "INFO" "[DRY RUN] Would verify files exist on AD2"
} else {
    # Check Sync-FromNAS.ps1 exists and has content
    $verifyCmd1 = "cmd /c if exist `"$REMOTE_SYNC_PATH`" (echo FILE_EXISTS) else (echo FILE_MISSING)"
    $verify1 = Invoke-AD2Command $verifyCmd1 | Out-String
    if ($verify1 -match "FILE_EXISTS") {
        Write-Status "OK" "Verified: Sync-FromNAS.ps1 exists on AD2"
    } else {
        Write-Status "ERROR" "Verification failed: Sync-FromNAS.ps1 not found on AD2"
        exit 1
    }

    # Check import.js exists
    $verifyCmd2 = "cmd /c if exist `"$REMOTE_IMPORT_PATH`" (echo FILE_EXISTS) else (echo FILE_MISSING)"
    $verify2 = Invoke-AD2Command $verifyCmd2 | Out-String
    if ($verify2 -match "FILE_EXISTS") {
        Write-Status "OK" "Verified: import.js exists on AD2"
    } else {
        Write-Status "ERROR" "Verification failed: import.js not found on AD2"
        exit 1
    }
}

# ============================================================================
# Step 5: Quick dry-run test of the sync script
# ============================================================================
Write-Host ""
Write-Status "INFO" "--- Step 5: Running dry-run test of sync script ---"

if ($DryRun) {
    Write-Status "INFO" "[DRY RUN] Would run: powershell -ExecutionPolicy Bypass -File $REMOTE_SYNC_PATH -DryRun"
} else {
    Write-Status "INFO" "Executing sync script in dry-run mode on AD2..."
    $testCmd = "powershell -ExecutionPolicy Bypass -File `"$REMOTE_SYNC_PATH`" -DryRun -Verbose"
    $testResult = Invoke-AD2Command $testCmd
    $testOutput = $testResult | Out-String

    # Check if the script ran without critical errors
    if ($LASTEXITCODE -eq 0) {
        Write-Status "OK" "Sync script dry-run completed successfully"
        if ($testOutput.Trim().Length -gt 0) {
            Write-Host ""
            Write-Host "  --- Dry-run output ---"
            foreach ($line in ($testResult | Select-Object -First 20)) {
                Write-Host "  $line"
            }
            $totalLines = ($testResult | Measure-Object).Count
            if ($totalLines -gt 20) {
                Write-Host "  ... ($($totalLines - 20) more lines)"
            }
            Write-Host "  --- End dry-run output ---"
        }
    } else {
        Write-Status "WARNING" "Sync script dry-run exited with code $LASTEXITCODE"
        Write-Status "INFO" "This may be expected if NAS is unreachable from AD2 during test"
        if ($testOutput.Trim().Length -gt 0) {
            Write-Host ""
            Write-Host "  --- Dry-run output ---"
            foreach ($line in ($testResult | Select-Object -First 10)) {
                Write-Host "  $line"
            }
            Write-Host "  --- End dry-run output ---"
        }
    }
}

# ============================================================================
# Summary
# ============================================================================
Write-Host ""
Write-Host "============================================"
Write-Host "  Deployment Summary"
Write-Host "============================================"
Write-Host ""

if ($DryRun) {
    Write-Status "INFO" "DRY RUN complete - no changes were made"
} else {
    Write-Status "OK" "Sync-FromNAS.ps1 deployed to AD2 (backup: .bak-${DATE_SUFFIX})"
    Write-Status "OK" "import.js deployed to AD2 (backup: .bak-${DATE_SUFFIX})"
    Write-Status "OK" ".ssh directory and known_hosts verified"
    Write-Status "OK" "Dry-run test executed"
    Write-Host ""
    Write-Status "INFO" "Fixes applied:"
    Write-Host "  1. PULL hang fix: find output written to temp file, pulled via SCP"
    Write-Host "  2. SCP quoting fix: remote paths quoted to handle special characters"
    Write-Host "  3. Rename-OnNAS: files renamed to .synced instead of deleted"
    Write-Host "  4. INSERT OR REPLACE: re-tested devices keep latest result"
    Write-Host ""
    Write-Status "INFO" "Next sync cycle will use the patched scripts automatically"
}

Write-Host ""
exit 0
