#!/usr/bin/env python3
"""
OneClarity Teams Onboarding
----------------------------
Run once as a Microsoft 365 Teams Administrator to grant transcript access.

Requirements:
  - Python 3.8+
  - PowerShell 7 (pwsh) on macOS/Linux  OR  Windows PowerShell 5+ on Windows
  - A Teams Administrator or Global Administrator account to sign in with
"""
from __future__ import annotations
import os
import shutil
import subprocess
import sys
import tempfile
import textwrap

# ─── Pre-filled by the portal when this file is downloaded ────────────────────
APP_CLIENT_ID = "9231ae82-4486-426e-b80b-081ce800bd60"
POLICY_NAME   = "OneClarityTranscriptAccess"
# ──────────────────────────────────────────────────────────────────────────────

PS_SCRIPT = textwrap.dedent(f"""\
    $ErrorActionPreference = 'Stop'

    Write-Host ""
    Write-Host "Step 1/3  Checking MicrosoftTeams PowerShell module..." -ForegroundColor Cyan
    if (-not (Get-Module -ListAvailable -Name MicrosoftTeams)) {{
        Write-Host "          Installing (first run only, ~30 s)..." -ForegroundColor Yellow
        if (-not (Get-PackageProvider -Name NuGet -ErrorAction SilentlyContinue)) {{
            Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Scope CurrentUser | Out-Null
        }}
        Install-Module -Name MicrosoftTeams -Force -AllowClobber -Scope CurrentUser -Repository PSGallery
        Write-Host "          Installed." -ForegroundColor Green
    }} else {{
        Write-Host "          Already installed." -ForegroundColor Green
    }}
    try {{
        Import-Module MicrosoftTeams -Force -ErrorAction Stop
    }} catch {{
        Write-Host "ERROR: Could not load MicrosoftTeams module: $_" -ForegroundColor Red
        Write-Host "       Try: Install-Module MicrosoftTeams -Force -Scope CurrentUser" -ForegroundColor Yellow
        exit 1
    }}

    Write-Host ""
    Write-Host "Step 2/3  Connecting to Microsoft Teams..." -ForegroundColor Cyan
    Write-Host "          A browser window will open. Sign in as a Teams Administrator."
    $session = Connect-MicrosoftTeams
    if (-not $session) {{
        Write-Host "ERROR: Sign-in failed or was cancelled." -ForegroundColor Red
        exit 1
    }}
    Write-Host "          Signed in as: $($session.Account)" -ForegroundColor Green
    Write-Host "          Tenant:       $($session.TenantId)" -ForegroundColor Green

    Write-Host ""
    Write-Host "Step 3/3  Configuring Application Access Policy..." -ForegroundColor Cyan
    $policyName = "{POLICY_NAME}"
    $appId      = "{APP_CLIENT_ID}"

    if ([string]::IsNullOrWhiteSpace($appId)) {{
        Write-Host "ERROR: App Client ID is empty. Contact OneClarity support." -ForegroundColor Red
        exit 1
    }}

    try {{
        $existing = Get-CsApplicationAccessPolicy -Identity $policyName -ErrorAction Stop
    }} catch {{
        $existing = $null
    }}

    $justCreated = $false
    if ($null -eq $existing) {{
        try {{
            New-CsApplicationAccessPolicy `
                -Identity    $policyName `
                -AppIds      @($appId) `
                -Description "Grants OneClarity read access to Teams meeting transcripts"
            Write-Host "          Policy created." -ForegroundColor Green
            $justCreated = $true
        }} catch {{
            Write-Host "ERROR: Could not create policy: $_" -ForegroundColor Red
            Write-Host "       Ensure the signed-in account has the Teams Administrator role." -ForegroundColor Yellow
            exit 1
        }}
    }} else {{
        Write-Host "          Policy already exists, skipping creation." -ForegroundColor Yellow
    }}

    if ($justCreated) {{
        Write-Host "          Waiting 15 s for policy replication..." -ForegroundColor Yellow
        Start-Sleep -Seconds 15
    }}

    try {{
        Grant-CsApplicationAccessPolicy -PolicyName $policyName -Global
        Write-Host "          Policy applied to all users in the tenant." -ForegroundColor Green
    }} catch {{
        Write-Host "ERROR: Grant-CsApplicationAccessPolicy failed: $_" -ForegroundColor Red
        Write-Host "       If 'policy not found', wait 2 minutes and re-run." -ForegroundColor Yellow
        exit 1
    }}

    Write-Host ""
    Write-Host "==========================================" -ForegroundColor Green
    Write-Host " Setup complete!" -ForegroundColor Green
    Write-Host " Application Access Policy is configured." -ForegroundColor Green
    Write-Host "==========================================" -ForegroundColor Green
    Write-Host ""
""")


def find_powershell() -> str | None:
    """Return the first available PowerShell executable, preferring PS7."""
    for cmd in ("pwsh", "powershell"):
        if shutil.which(cmd):
            return cmd
    return None


def main() -> None:
    print()
    print("OneClarity Teams Onboarding")
    print("=" * 44)

    ps = find_powershell()
    if not ps:
        print()
        print("ERROR: PowerShell was not found on this machine.")
        print()
        if sys.platform == "darwin":
            print("  Install PowerShell 7 via Homebrew, then re-run this script:")
            print()
            print("    brew install --cask powershell")
        else:
            print("  PowerShell is built into Windows and should be available.")
            print("  Try opening a new terminal window and running again.")
        print()
        sys.exit(1)

    print(f"PowerShell found  : {ps}")
    print(f"App client ID     : {APP_CLIENT_ID}")
    print(f"Policy name       : {POLICY_NAME}")
    print()

    # Write the script to a temp file to avoid command-line length limits
    # and cross-platform escaping issues when using -Command.
    tmp = tempfile.NamedTemporaryFile(
        mode="w", suffix=".ps1", delete=False, encoding="utf-8"
    )
    try:
        tmp.write(PS_SCRIPT)
        tmp.close()

        result = subprocess.run(
            [ps, "-ExecutionPolicy", "Bypass", "-File", tmp.name],
        )
    finally:
        os.unlink(tmp.name)

    if result.returncode != 0:
        print()
        print(f"Setup failed (PowerShell exited with code {result.returncode}).")
        print("Review the output above for details.")
        print()
        sys.exit(result.returncode)


if __name__ == "__main__":
    main()
