functions/ScheduledTask.ps1

# Cross-Platform Scheduled Task Support for EmojiTools

function Get-EmojiPlatform {
    <#
    .SYNOPSIS
        Detects the current operating system platform.

    .DESCRIPTION
        Returns 'Windows', 'Linux', or 'macOS' based on the current platform.
        Used internally for cross-platform scheduled task support.

    .OUTPUTS
        String - Platform name

    .EXAMPLE
        Get-EmojiPlatform
        Returns: Windows
    #>


    if ($PSVersionTable.PSVersion.Major -ge 6) {
        # PowerShell Core 6+ has $IsWindows, $IsLinux, $IsMacOS
        if ($IsWindows) { return 'Windows' }
        if ($IsLinux) { return 'Linux' }
        if ($IsMacOS) { return 'macOS' }
    }
    else {
        # PowerShell 5.1 and earlier are Windows-only
        return 'Windows'
    }

    # Fallback
    if ($env:OS -match 'Windows') { return 'Windows' }
    if (Test-Path '/proc/version') { return 'Linux' }
    if (Test-Path '/System/Library/CoreServices/SystemVersion.plist') { return 'macOS' }

    return 'Unknown'
}


function Get-PowerShellPath {
    <#
    .SYNOPSIS
        Gets the full path to the PowerShell executable.

    .DESCRIPTION
        Returns the path to pwsh or powershell.exe based on the current environment.
        Handles different installation locations across platforms.

    .OUTPUTS
        String - Full path to PowerShell executable
    #>


    # Try to get current PowerShell executable
    if ($PSVersionTable.PSVersion.Major -ge 6) {
        # PowerShell Core - try to find pwsh
        $pwshPath = (Get-Command pwsh -ErrorAction SilentlyContinue).Source
        if ($pwshPath) { return $pwshPath }

        # Common locations
        $commonPaths = @(
            '/usr/bin/pwsh'
            '/usr/local/bin/pwsh'
            'C:\Program Files\PowerShell\7\pwsh.exe'
            "$env:ProgramFiles\PowerShell\7\pwsh.exe"
        )

        foreach ($path in $commonPaths) {
            if (Test-Path $path) { return $path }
        }
    }
    else {
        # PowerShell 5.1 - Windows only
        return 'PowerShell.exe'
    }

    # Last resort - use what launched us
    return $PSHOME + [IO.Path]::DirectorySeparatorChar + 'pwsh'
}


function New-EmojiScheduledTask {
    <#
    .SYNOPSIS
        Creates a cross-platform scheduled task for automatic emoji updates.

    .DESCRIPTION
        Creates a platform-specific scheduled task that runs Update-EmojiDataset
        at the specified interval. Supports Windows Task Scheduler, Linux cron,
        and macOS launchd.

    .PARAMETER Interval
        Update interval in days (default: 7)

    .PARAMETER Silent
        Suppress output messages

    .OUTPUTS
        Boolean - True if task was created successfully

    .EXAMPLE
        New-EmojiScheduledTask -Interval 7
        Creates a task to update emojis every 7 days

    .EXAMPLE
        New-EmojiScheduledTask -Interval 14
        Creates a task to update emojis every 14 days
    #>


    [CmdletBinding(SupportsShouldProcess)]
    [OutputType([bool])]
    param(
        [Parameter(Mandatory = $false)]
        [ValidateRange(1, 365)]
        [int]$Interval = 7,

        [Parameter(Mandatory = $false)]
        [switch]$Silent
    )

    $platform = Get-EmojiPlatform

    if (-not $Silent) {
        Write-Verbose "Platform detected: $platform"
    }

    try {
        switch ($platform) {
            'Windows' {
                return New-WindowsScheduledTask -Interval $Interval -Silent:$Silent
            }
            'Linux' {
                return New-LinuxCronJob -Interval $Interval -Silent:$Silent
            }
            'macOS' {
                return New-MacOSLaunchAgent -Interval $Interval -Silent:$Silent
            }
            default {
                Write-Error "Unsupported platform: $platform"
                return $false
            }
        }
    }
    catch {
        Write-Error "Failed to create scheduled task: $_"
        return $false
    }
}


function Remove-EmojiScheduledTask {
    <#
    .SYNOPSIS
        Removes the emoji auto-update scheduled task.

    .DESCRIPTION
        Removes the platform-specific scheduled task created by New-EmojiScheduledTask.
        Supports Windows Task Scheduler, Linux cron, and macOS launchd.

    .PARAMETER Silent
        Suppress output messages

    .OUTPUTS
        Boolean - True if task was removed successfully or didn't exist

    .EXAMPLE
        Remove-EmojiScheduledTask
        Removes the scheduled task for the current platform
    #>


    [CmdletBinding(SupportsShouldProcess)]
    [OutputType([bool])]
    param(
        [Parameter(Mandatory = $false)]
        [switch]$Silent
    )

    $platform = Get-EmojiPlatform

    try {
        switch ($platform) {
            'Windows' {
                return Remove-WindowsScheduledTask -Silent:$Silent
            }
            'Linux' {
                return Remove-LinuxCronJob -Silent:$Silent
            }
            'macOS' {
                return Remove-MacOSLaunchAgent -Silent:$Silent
            }
            default {
                Write-Error "Unsupported platform: $platform"
                return $false
            }
        }
    }
    catch {
        Write-Error "Failed to remove scheduled task: $_"
        return $false
    }
}


function Test-EmojiScheduledTask {
    <#
    .SYNOPSIS
        Checks if an emoji auto-update scheduled task exists.

    .DESCRIPTION
        Verifies whether a scheduled task for emoji updates is currently configured
        on the system. Platform-aware.

    .OUTPUTS
        Boolean - True if task exists

    .EXAMPLE
        Test-EmojiScheduledTask
        Returns True if a task is configured
    #>


    [CmdletBinding()]
    [OutputType([bool])]
    param()

    $platform = Get-EmojiPlatform

    try {
        switch ($platform) {
            'Windows' {
                return Test-WindowsScheduledTask
            }
            'Linux' {
                return Test-LinuxCronJob
            }
            'macOS' {
                return Test-MacOSLaunchAgent
            }
            default {
                return $false
            }
        }
    }
    catch {
        return $false
    }
}


#region Windows Implementation

function New-WindowsScheduledTask {
    [CmdletBinding(SupportsShouldProcess)]
    [OutputType([bool])]
    param(
        [int]$Interval = 7,
        [switch]$Silent
    )

    $taskName = "EmojiTools-AutoUpdate"
    $taskDescription = "Automatically updates emoji dataset from Unicode CLDR every $Interval days"

    if (-not $PSCmdlet.ShouldProcess($taskName, "Create scheduled task")) {
        return $false
    }

    try {
        $pwshPath = Get-PowerShellPath

        $action = New-ScheduledTaskAction -Execute $pwshPath -Argument `
            "-NoProfile -WindowStyle Hidden -Command `"Import-Module EmojiTools; Update-EmojiDataset -Source Unicode -Silent`""

        $trigger = New-ScheduledTaskTrigger -Daily -At "03:00AM" -DaysInterval $Interval

        $settings = New-ScheduledTaskSettingsSet `
            -AllowStartIfOnBatteries `
            -DontStopIfGoingOnBatteries `
            -StartWhenAvailable `
            -RunOnlyIfNetworkAvailable

        Register-ScheduledTask -TaskName $taskName `
            -Description $taskDescription `
            -Action $action `
            -Trigger $trigger `
            -Settings $settings `
            -Force | Out-Null

        if (-not $Silent) {
            Write-Host "✅ Scheduled task created: $taskName" -ForegroundColor Green
            Write-Host " Runs daily at 3:00 AM (every $Interval days)" -ForegroundColor White
            Write-Host " View with: Get-ScheduledTask -TaskName '$taskName'" -ForegroundColor Cyan
        }

        return $true
    }
    catch {
        if (-not $Silent) {
            Write-Warning "Failed to create Windows scheduled task: $_"
        }
        return $false
    }
}


function Remove-WindowsScheduledTask {
    [CmdletBinding(SupportsShouldProcess)]
    [OutputType([bool])]
    param([switch]$Silent)

    $taskName = "EmojiTools-AutoUpdate"

    if (-not $PSCmdlet.ShouldProcess($taskName, "Remove scheduled task")) {
        return $false
    }

    try {
        $task = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
        if ($task) {
            Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
            if (-not $Silent) {
                Write-Host "✅ Removed scheduled task: $taskName" -ForegroundColor Green
            }
            return $true
        }
        else {
            if (-not $Silent) {
                Write-Host "ℹ️ No scheduled task found" -ForegroundColor Yellow
            }
            return $true
        }
    }
    catch {
        if (-not $Silent) {
            Write-Warning "Failed to remove Windows scheduled task: $_"
        }
        return $false
    }
}


function Test-WindowsScheduledTask {
    [CmdletBinding()]
    [OutputType([bool])]
    param()

    try {
        $task = Get-ScheduledTask -TaskName "EmojiTools-AutoUpdate" -ErrorAction SilentlyContinue
        return ($null -ne $task)
    }
    catch {
        return $false
    }
}

#endregion


#region Linux Implementation

function New-LinuxCronJob {
    [CmdletBinding(SupportsShouldProcess)]
    [OutputType([bool])]
    param(
        [int]$Interval = 7,
        [switch]$Silent
    )

    if (-not $PSCmdlet.ShouldProcess("crontab", "Add EmojiTools auto-update job")) {
        return $false
    }

    try {
        $pwshPath = Get-PowerShellPath

        # Build cron schedule expression
        # For daily at 3 AM: 0 3 */N * *
        # N = interval in days
        $cronSchedule = "0 3 */$Interval * *"

        # Command to run
        $command = "$pwshPath -NoProfile -Command 'Import-Module EmojiTools; Update-EmojiDataset -Source Unicode -Silent'"

        # Full cron entry with comment for identification
        $cronEntry = "$cronSchedule $command # EmojiTools-AutoUpdate"

        # Get current crontab (may be empty)
        $currentCrontab = & crontab -l 2>$null

        # Check if our job already exists
        if ($currentCrontab -match 'EmojiTools-AutoUpdate') {
            # Remove existing entry
            $currentCrontab = $currentCrontab | Where-Object { $_ -notmatch 'EmojiTools-AutoUpdate' }
        }

        # Add our new entry
        $newCrontab = if ($currentCrontab) {
            @($currentCrontab) + $cronEntry
        }
        else {
            @($cronEntry)
        }

        # Write to crontab
        $newCrontab | & crontab -

        if (-not $Silent) {
            Write-Host "✅ Cron job created: EmojiTools-AutoUpdate" -ForegroundColor Green
            Write-Host " Schedule: Daily at 3:00 AM (every $Interval days)" -ForegroundColor White
            Write-Host " View with: crontab -l | grep EmojiTools" -ForegroundColor Cyan
        }

        return $true
    }
    catch {
        if (-not $Silent) {
            Write-Warning "Failed to create Linux cron job: $_"
            Write-Host " You may need to install cron or have proper permissions" -ForegroundColor Yellow
        }
        return $false
    }
}


function Remove-LinuxCronJob {
    [CmdletBinding(SupportsShouldProcess)]
    [OutputType([bool])]
    param([switch]$Silent)

    if (-not $PSCmdlet.ShouldProcess("crontab", "Remove EmojiTools auto-update job")) {
        return $false
    }

    try {
        # Get current crontab
        $currentCrontab = & crontab -l 2>$null

        if ($currentCrontab -match 'EmojiTools-AutoUpdate') {
            # Remove our entry
            $newCrontab = $currentCrontab | Where-Object { $_ -notmatch 'EmojiTools-AutoUpdate' }

            if ($newCrontab) {
                $newCrontab | & crontab -
            }
            else {
                # Empty crontab - remove it entirely
                & crontab -r 2>$null
            }

            if (-not $Silent) {
                Write-Host "✅ Removed cron job: EmojiTools-AutoUpdate" -ForegroundColor Green
            }
            return $true
        }
        else {
            if (-not $Silent) {
                Write-Host "ℹ️ No cron job found" -ForegroundColor Yellow
            }
            return $true
        }
    }
    catch {
        if (-not $Silent) {
            Write-Warning "Failed to remove Linux cron job: $_"
        }
        return $false
    }
}


function Test-LinuxCronJob {
    [CmdletBinding()]
    [OutputType([bool])]
    param()

    try {
        $currentCrontab = & crontab -l 2>$null
        if ($null -eq $currentCrontab) {
            return $false
        }
        return ($currentCrontab -match 'EmojiTools-AutoUpdate')
    }
    catch {
        return $false
    }
}

#endregion


#region macOS Implementation

function New-MacOSLaunchAgent {
    [CmdletBinding(SupportsShouldProcess)]
    [OutputType([bool])]
    param(
        [int]$Interval = 7,
        [switch]$Silent
    )

    $agentName = "com.emojitools.autoupdate"
    $agentPath = "$env:HOME/Library/LaunchAgents/$agentName.plist"

    if (-not $PSCmdlet.ShouldProcess($agentPath, "Create LaunchAgent")) {
        return $false
    }

    try {
        # Ensure LaunchAgents directory exists
        $agentDir = "$env:HOME/Library/LaunchAgents"
        if (-not (Test-Path $agentDir)) {
            New-Item -ItemType Directory -Path $agentDir -Force | Out-Null
        }

        $pwshPath = Get-PowerShellPath
        $intervalSeconds = $Interval * 86400  # Convert days to seconds

        # Generate plist XML
        $plistContent = @"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>$agentName</string>
    <key>ProgramArguments</key>
    <array>
        <string>$pwshPath</string>
        <string>-NoProfile</string>
        <string>-Command</string>
        <string>Import-Module EmojiTools; Update-EmojiDataset -Source Unicode -Silent</string>
    </array>
    <key>StartInterval</key>
    <integer>$intervalSeconds</integer>
    <key>RunAtLoad</key>
    <false/>
    <key>StandardOutPath</key>
    <string>$env:HOME/Library/Logs/EmojiTools-AutoUpdate.log</string>
    <key>StandardErrorPath</key>
    <string>$env:HOME/Library/Logs/EmojiTools-AutoUpdate.error.log</string>
</dict>
</plist>
"@


        # Write plist file
        $plistContent | Out-File -FilePath $agentPath -Encoding UTF8

        # Load the agent
        & launchctl load $agentPath 2>$null

        if (-not $Silent) {
            Write-Host "✅ LaunchAgent created: $agentName" -ForegroundColor Green
            Write-Host " Runs every $Interval days" -ForegroundColor White
            Write-Host " Config: $agentPath" -ForegroundColor Cyan
            Write-Host " Logs: ~/Library/Logs/EmojiTools-AutoUpdate.log" -ForegroundColor Cyan
        }

        return $true
    }
    catch {
        if (-not $Silent) {
            Write-Warning "Failed to create macOS LaunchAgent: $_"
        }
        return $false
    }
}


function Remove-MacOSLaunchAgent {
    [CmdletBinding(SupportsShouldProcess)]
    [OutputType([bool])]
    param([switch]$Silent)

    $agentName = "com.emojitools.autoupdate"
    $agentPath = "$env:HOME/Library/LaunchAgents/$agentName.plist"

    if (-not $PSCmdlet.ShouldProcess($agentPath, "Remove LaunchAgent")) {
        return $false
    }

    try {
        if (Test-Path $agentPath) {
            # Unload the agent
            & launchctl unload $agentPath 2>$null

            # Remove the plist file
            Remove-Item $agentPath -Force

            if (-not $Silent) {
                Write-Host "✅ Removed LaunchAgent: $agentName" -ForegroundColor Green
            }
            return $true
        }
        else {
            if (-not $Silent) {
                Write-Host "ℹ️ No LaunchAgent found" -ForegroundColor Yellow
            }
            return $true
        }
    }
    catch {
        if (-not $Silent) {
            Write-Warning "Failed to remove macOS LaunchAgent: $_"
        }
        return $false
    }
}


function Test-MacOSLaunchAgent {
    [CmdletBinding()]
    [OutputType([bool])]
    param()

    $agentPath = "$env:HOME/Library/LaunchAgents/com.emojitools.autoupdate.plist"
    return (Test-Path $agentPath)
}

#endregion