# Samy.Datto.ps1
# Datto RMM helper and HTTP handlers

function Invoke-FetchSites {
    param($Context)

    try {
        $raw = (New-Object IO.StreamReader $Context.Request.InputStream).ReadToEnd()
        $pw  = (ConvertFrom-Json $raw).password

        $Global:WebhookPassword = $pw

        $sites = Install-DattoRMM `
            -UseWebhook `
            -WebhookPassword $pw `
            -FetchSites

        Send-JSON $Context $sites
    }
    catch {
        Write-LogHybrid "Invoke-FetchSites error: $($_.Exception.Message)" Error DattoRMM -LogToEvent
        $Context.Response.StatusCode = 500
        Send-Text $Context "Internal server error fetching sites."
    }
}

function Invoke-InstallDattoRMM {
    param($Context)

    try {
        if ($Context.Request.HttpMethod -ne 'POST') {
            $Context.Response.StatusCode = 405
            Send-Text $Context 'Use POST'
            return
        }

        $body = (New-Object IO.StreamReader $Context.Request.InputStream).ReadToEnd()
        $data = ConvertFrom-Json $body

        Install-DattoRMM `
            -UseWebhook `
            -WebhookPassword $Global:WebhookPassword `
            -SiteUID      $data.UID `
            -SiteName     $data.Name `
            -PushSiteVars:($data.checkedValues -contains 'inputVar') `
            -InstallRMM:   ($data.checkedValues -contains 'rmm') `
            -SaveCopy:     ($data.checkedValues -contains 'exe')

        Send-Text $Context "Triggered DattoRMM for $($data.Name)"
    }
    catch {
        Write-LogHybrid "Invoke-InstallDattoRMM error: $($_.Exception.Message)" Error DattoRMM -LogToEvent
        $Context.Response.StatusCode = 500
        Send-Text $Context "Internal server error during DattoRMM install."
    }
}

function Install-DattoRMM {
    [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium')]
    param (
        [switch]$UseWebhook,
        [string]$WebhookPassword,
        [string]$WebhookUrl    = $Global:DattoWebhookUrl,
        [string]$ApiUrl,
        [string]$ApiKey,
        [string]$ApiSecretKey,
        [switch]$FetchSites,
        [switch]$SaveSitesList,
        [string]$OutputFile      = 'datto_sites.csv',
        [switch]$PushSiteVars,
        [switch]$InstallRMM,
        [switch]$SaveCopy,
        [string]$SiteUID,
        [string]$SiteName
    )

    if ($SaveSitesList -and -not $FetchSites) {
        Write-LogHybrid "-SaveSitesList requires -FetchSites." Error DattoRMM -LogToEvent
        return
    }

    if ($UseWebhook) {
        if (-not $WebhookPassword) {
            Write-LogHybrid "Webhook password missing." Error DattoRMM -LogToEvent
            return
        }
        try {
            $resp = Invoke-RestMethod -Uri $WebhookUrl `
                                      -Headers @{ SVSMSPKit = $WebhookPassword } `
                                      -Method GET
            $ApiUrl       = $resp.ApiUrl
            $ApiKey       = $resp.ApiKey
            $ApiSecretKey = $resp.ApiSecretKey
            Write-LogHybrid "Webhook credentials fetched." Success DattoRMM -LogToEvent
        }
        catch {
            Write-LogHybrid "Failed to fetch webhook credentials: $($_.Exception.Message)" Error DattoRMM -LogToEvent
            return
        }
    }

    if (-not $ApiUrl -or -not $ApiKey -or -not $ApiSecretKey) {
        Write-LogHybrid "Missing required API parameters." Error DattoRMM -LogToEvent
        return
    }

    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    try {
        $publicCred = New-Object System.Management.Automation.PSCredential(
            'public-client', (ConvertTo-SecureString 'public' -AsPlainText -Force)
        )
        $tokenResp = Invoke-RestMethod -Uri "$ApiUrl/auth/oauth/token" `
                                       -Credential $publicCred `
                                       -Method Post `
                                       -ContentType 'application/x-www-form-urlencoded' `
                                       -Body "grant_type=password&username=$ApiKey&password=$ApiSecretKey"
        $token = $tokenResp.access_token
        Write-LogHybrid "OAuth token acquired." Success DattoRMM -LogToEvent
    }
    catch {
        Write-LogHybrid "OAuth token fetch failed: $($_.Exception.Message)" Error DattoRMM -LogToEvent
        return
    }
    $headers = @{ Authorization = "Bearer $token" }

    if ($FetchSites) {
        try {
            $sitesResp = Invoke-RestMethod -Uri "$ApiUrl/api/v2/account/sites" -Method Get -Headers $headers
            $siteList = $sitesResp.sites | Sort-Object name | ForEach-Object {
                [PSCustomObject]@{ Name = $_.name; UID = $_.uid }
            }
            Write-LogHybrid "Fetched $($siteList.Count) sites." Success DattoRMM -LogToEvent

            if ($SaveSitesList) {
                $desktop = [Environment]::GetFolderPath('Desktop')
                $path    = Join-Path $desktop $OutputFile
                $ext     = [IO.Path]::GetExtension($OutputFile).ToLower()
                if ($ext -eq '.json') {
                    $siteList | ConvertTo-Json -Depth 3 | Out-File -FilePath $path -Encoding UTF8
                }
                else {
                    $siteList | Export-Csv -Path $path -NoTypeInformation -Encoding UTF8
                }
                Write-LogHybrid "Wrote $($siteList.Count) sites to $path" Success DattoRMM -LogToEvent
            }

            return $siteList
        }
        catch {
            Write-LogHybrid "Failed to fetch sites: $($_.Exception.Message)" Error DattoRMM -LogToEvent
            return @()
        }
    }

    if ($PushSiteVars) {
        try {
            $varsResp = Invoke-RestMethod -Uri "$ApiUrl/api/v2/site/$SiteUID/variables" -Method Get -Headers $headers
            Write-LogHybrid "Fetched variables for '$SiteName'." Success DattoRMM -LogToEvent
        }
        catch {
            Write-LogHybrid "Variable fetch failed: $($_.Exception.Message)" Error DattoRMM -LogToEvent
        }

        $regPath = "HKLM:\Software\SVS\Deployment"
        foreach ($v in $varsResp.variables) {
            try {
                if (-not (Test-Path $regPath)) {
                    New-Item -Path $regPath -Force | Out-Null
                }
                New-ItemProperty -Path $regPath -Name $v.name -Value $v.value -PropertyType String -Force | Out-Null
                Write-LogHybrid "Wrote '$($v.name)' to registry." Success DattoRMM -LogToEvent
            }
            catch {
                Write-LogHybrid "Failed to write '$($v.name)': $($_.Exception.Message)" Error DattoRMM -LogToEvent
            }
        }
    }

    if ($InstallRMM) {
        if ($PSCmdlet.ShouldProcess("Site '$SiteName'", "Install RMM agent")) {
            try {
                $dlUrl = "https://zinfandel.centrastage.net/csm/profile/downloadAgent/$SiteUID"
                $tmp   = "$env:TEMP\AgentInstall.exe"
                Invoke-WebRequest -Uri $dlUrl -OutFile $tmp -UseBasicParsing
                Write-LogHybrid "Downloaded agent to $tmp." Info DattoRMM -LogToEvent
                Start-Process -FilePath $tmp -NoNewWindow
                Write-LogHybrid "RMM agent installer launched." Success DattoRMM -LogToEvent
            }
            catch {
                Write-LogHybrid "Agent install failed: $($_.Exception.Message)" Error DattoRMM -LogToEvent
            }
        }
    }

    if ($SaveCopy) {
        try {
            $dlUrl = "https://zinfandel.centrastage.net/csm/profile/downloadAgent/$SiteUID"
            $path  = "C:\Temp\AgentInstall.exe"
            if (-not (Test-Path 'C:\Temp')) {
                New-Item -Path 'C:\Temp' -ItemType Directory | Out-Null
            }
            Invoke-WebRequest -Uri $dlUrl -OutFile $path -UseBasicParsing
            Write-LogHybrid "Saved installer copy to $path." Info DattoRMM -LogToEvent
        }
        catch {
            Write-LogHybrid "Save-copy failed: $($_.Exception.Message)" Error DattoRMM -LogToEvent
        }
    }

    if (-not ($PushSiteVars -or $InstallRMM -or $SaveCopy)) {
        Write-LogHybrid "No action specified. Use -FetchSites, -SaveSitesList, -PushSiteVars, -InstallRMM, or -SaveCopy." Warning DattoRMM -LogToEvent
    }
}
