@echo off
setlocal EnableExtensions

REM ============================================================
REM  CODEx CLIENT BOOTSTRAP - Windows
REM  Auteur: setup generique pour clients non techniques
REM  Usage: double-cliquer ce fichier ou lancer depuis PowerShell/CMD.
REM ============================================================

title Installation environnement Codex client

REM --- Relance en administrateur si necessaire ---
net session >nul 2>&1
if %errorlevel% neq 0 (
    echo.
    echo [INFO] Droits administrateur requis pour installer les outils.
    echo [INFO] Une fenetre de confirmation Windows va s'ouvrir.
    powershell -NoProfile -ExecutionPolicy Bypass -Command "Start-Process -FilePath '%~f0' -Verb RunAs"
    exit /b
)

set "TEMP_PS1=%TEMP%\codex_client_bootstrap_%RANDOM%.ps1"

REM --- Extraire la partie PowerShell integree dans ce fichier ---
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
  "$lines = Get-Content -LiteralPath '%~f0';" ^
  "$marker = ($lines | Select-String -Pattern '^# POWERSHELL_START$' | Select-Object -First 1).LineNumber;" ^
  "if (-not $marker) { throw 'Marker PowerShell introuvable.' };" ^
  "$lines[$marker..($lines.Length-1)] | Set-Content -LiteralPath '%TEMP_PS1%' -Encoding UTF8"

if not exist "%TEMP_PS1%" (
    echo [ERREUR] Impossible de preparer le script PowerShell.
    pause
    exit /b 1
)

powershell -NoProfile -ExecutionPolicy Bypass -File "%TEMP_PS1%"
set "EXITCODE=%ERRORLEVEL%"

del "%TEMP_PS1%" >nul 2>&1

echo.
if "%EXITCODE%"=="0" (
    echo Installation terminee. Tu peux fermer cette fenetre.
) else (
    echo Installation terminee avec erreurs. Consulte le rapport dans Codex-Workspace.
)
echo.
pause
exit /b %EXITCODE%

# POWERSHELL_START
$ErrorActionPreference = "Stop"

# ============================================================
#  CONFIGURATION
# ============================================================
$BootstrapRoot = Join-Path $env:USERPROFILE "Codex-Workspace"
$LogDir        = Join-Path $BootstrapRoot "_installation_logs"
$ReportPath    = Join-Path $BootstrapRoot "rapport-installation.txt"
$StartHerePath = Join-Path $BootstrapRoot "START_HERE.txt"
$AgentPath     = Join-Path $BootstrapRoot "AGENTS.md"
$CodexDir      = Join-Path $env:USERPROFILE ".codex"
$CodexConfig   = Join-Path $CodexDir "config.toml"

$Packages = @(
    @{ Id = "Git.Git"; Name = "Git" },
    @{ Id = "Microsoft.VisualStudioCode"; Name = "Visual Studio Code" },
    @{ Id = "OpenJS.NodeJS.LTS"; Name = "Node.js LTS" },
    @{ Id = "Python.Python.3.12"; Name = "Python 3.12" },
    @{ Id = "GitHub.cli"; Name = "GitHub CLI" },
    @{ Id = "Microsoft.PowerShell"; Name = "PowerShell 7" }
)

# Docker est volontairement optionnel: lourd, redemarrage possible, contraintes entreprise.
$InstallDocker = $false

# ============================================================
#  HELPERS
# ============================================================
function Write-Step {
    param([string]$Message)
    Write-Host ""
    Write-Host "=== $Message ===" -ForegroundColor Cyan
}

function Write-Ok {
    param([string]$Message)
    Write-Host "[OK] $Message" -ForegroundColor Green
}

function Write-Warn2 {
    param([string]$Message)
    Write-Host "[ATTENTION] $Message" -ForegroundColor Yellow
}

function Write-Fail {
    param([string]$Message)
    Write-Host "[ERREUR] $Message" -ForegroundColor Red
}

function Add-Report {
    param([string]$Line)
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    "$timestamp  $Line" | Out-File -FilePath $ReportPath -Encoding UTF8 -Append
}

function Refresh-Path {
    $machine = [Environment]::GetEnvironmentVariable("Path", "Machine")
    $user    = [Environment]::GetEnvironmentVariable("Path", "User")
    $env:Path = "$machine;$user"
}

function Test-CommandExists {
    param([string]$CommandName)
    $null -ne (Get-Command $CommandName -ErrorAction SilentlyContinue)
}

function Install-WingetPackage {
    param(
        [string]$Id,
        [string]$Name
    )

    try {
        Write-Host "Verification: $Name"
        $installed = winget list --id $Id -e 2>$null | Select-String -SimpleMatch $Id

        if ($installed) {
            Write-Ok "$Name deja installe."
            Add-Report "OK - $Name deja installe."
            return
        }

        Write-Host "Installation: $Name"
        winget install --id $Id -e `
            --accept-package-agreements `
            --accept-source-agreements `
            --silent

        if ($LASTEXITCODE -eq 0) {
            Write-Ok "$Name installe."
            Add-Report "OK - $Name installe."
        } else {
            Write-Warn2 "$Name n'a pas confirme une installation complete. Code: $LASTEXITCODE"
            Add-Report "WARN - $Name installation incertaine. Code: $LASTEXITCODE"
        }
    } catch {
        Write-Warn2 "Impossible d'installer $Name : $($_.Exception.Message)"
        Add-Report "ERROR - $Name : $($_.Exception.Message)"
    }
}

function Create-Shortcut {
    param(
        [string]$ShortcutPath,
        [string]$TargetPath,
        [string]$Arguments,
        [string]$WorkingDirectory,
        [string]$Description
    )

    try {
        $shell = New-Object -ComObject WScript.Shell
        $shortcut = $shell.CreateShortcut($ShortcutPath)
        $shortcut.TargetPath = $TargetPath
        $shortcut.Arguments = $Arguments
        $shortcut.WorkingDirectory = $WorkingDirectory
        $shortcut.Description = $Description
        $shortcut.Save()
        Write-Ok "Raccourci cree: $ShortcutPath"
        Add-Report "OK - Raccourci cree: $ShortcutPath"
    } catch {
        Write-Warn2 "Raccourci non cree: $($_.Exception.Message)"
        Add-Report "WARN - Raccourci non cree: $($_.Exception.Message)"
    }
}

# ============================================================
#  DOSSIERS ET JOURNAL
# ============================================================
New-Item -ItemType Directory -Force -Path $BootstrapRoot | Out-Null
New-Item -ItemType Directory -Force -Path $LogDir | Out-Null
New-Item -ItemType Directory -Force -Path $CodexDir | Out-Null
"Rapport installation Codex client" | Out-File -FilePath $ReportPath -Encoding UTF8
"Utilisateur: $env:USERNAME" | Out-File -FilePath $ReportPath -Encoding UTF8 -Append
"Machine: $env:COMPUTERNAME" | Out-File -FilePath $ReportPath -Encoding UTF8 -Append
"Date: $(Get-Date)" | Out-File -FilePath $ReportPath -Encoding UTF8 -Append
"" | Out-File -FilePath $ReportPath -Encoding UTF8 -Append

Write-Host ""
Write-Host "====================================================" -ForegroundColor Magenta
Write-Host " INSTALLATION ENVIRONNEMENT CODEX CLIENT" -ForegroundColor Magenta
Write-Host "====================================================" -ForegroundColor Magenta
Write-Host "Dossier de travail: $BootstrapRoot"

# ============================================================
#  SYSTEME
# ============================================================
Write-Step "Verification Windows et winget"

$os = Get-CimInstance Win32_OperatingSystem
Add-Report "OS - $($os.Caption) / Build $($os.BuildNumber)"

if (-not (Test-CommandExists "winget")) {
    Write-Fail "winget est absent. Installe/Appelle 'App Installer' depuis Microsoft Store, puis relance ce fichier."
    Add-Report "ERROR - winget absent."
    exit 1
}

Write-Ok "winget disponible."
Add-Report "OK - winget disponible."

# ============================================================
#  INSTALLATION OUTILS
# ============================================================
Write-Step "Installation des outils de base"

foreach ($pkg in $Packages) {
    Install-WingetPackage -Id $pkg.Id -Name $pkg.Name
}

if ($InstallDocker) {
    Install-WingetPackage -Id "Docker.DockerDesktop" -Name "Docker Desktop"
} else {
    Add-Report "INFO - Docker Desktop non installe par defaut."
}

Refresh-Path

# ============================================================
#  CONFIG GIT
# ============================================================
Write-Step "Configuration Git minimale"

try {
    if (Test-CommandExists "git") {
        git config --global init.defaultBranch main
        git config --global pull.rebase false
        git config --global core.autocrlf true
        git config --global core.longpaths true
        Write-Ok "Git configure."
        Add-Report "OK - Git configure."
    } else {
        Write-Warn2 "Git non detecte dans cette session. Il sera peut-etre disponible apres reouverture du terminal."
        Add-Report "WARN - Git non detecte."
    }
} catch {
    Write-Warn2 "Configuration Git incomplete: $($_.Exception.Message)"
    Add-Report "WARN - Config Git incomplete: $($_.Exception.Message)"
}

# ============================================================
#  INSTALL CODEX CLI
# ============================================================
Write-Step "Installation Codex CLI"

$codexInstalled = $false

try {
    Write-Host "Tentative via l'installateur officiel Windows..."
    $env:CODEX_NON_INTERACTIVE = "1"
    powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://chatgpt.com/codex/install.ps1 | iex"
    Refresh-Path

    if (Test-CommandExists "codex") {
        $codexInstalled = $true
        Write-Ok "Codex CLI installe via installateur officiel."
        Add-Report "OK - Codex CLI installe via installateur officiel."
    }
} catch {
    Write-Warn2 "Installateur officiel non termine: $($_.Exception.Message)"
    Add-Report "WARN - Installateur officiel Codex: $($_.Exception.Message)"
}

if (-not $codexInstalled) {
    try {
        Refresh-Path
        if (Test-CommandExists "npm") {
            Write-Host "Fallback via npm: npm install -g @openai/codex@latest"
            npm install -g "@openai/codex@latest"
            Refresh-Path
            if (Test-CommandExists "codex") {
                $codexInstalled = $true
                Write-Ok "Codex CLI installe via npm."
                Add-Report "OK - Codex CLI installe via npm."
            }
        } else {
            Write-Warn2 "npm indisponible dans cette session. Relancer le fichier apres installation Node.js."
            Add-Report "WARN - npm indisponible."
        }
    } catch {
        Write-Warn2 "Installation Codex via npm incomplete: $($_.Exception.Message)"
        Add-Report "WARN - Codex npm incomplete: $($_.Exception.Message)"
    }
}

# ============================================================
#  CONFIG CODEX SECURISEE
# ============================================================
Write-Step "Configuration Codex securisee"

$ConfigContent = @"
# Configuration generee par install_codex_client.cmd
# Objectif: permettre a Codex de travailler dans le dossier du projet sans acces illimite.

# Codex demande confirmation lorsqu'il veut sortir du cadre autorise.
approval_policy = "on-request"

# Codex peut lire/modifier le workspace courant, mais pas toute la machine.
sandbox_mode = "workspace-write"

# Sur Windows, le mode elevated est recommande quand disponible.
[windows]
sandbox = "elevated"
sandbox_private_desktop = true
"@

try {
    $ConfigContent | Out-File -FilePath $CodexConfig -Encoding UTF8 -Force
    Write-Ok "Config Codex creee: $CodexConfig"
    Add-Report "OK - Config Codex creee: $CodexConfig"
} catch {
    Write-Warn2 "Config Codex non creee: $($_.Exception.Message)"
    Add-Report "WARN - Config Codex non creee: $($_.Exception.Message)"
}

# ============================================================
#  AGENTS.MD GENERIQUE
# ============================================================
Write-Step "Creation du fichier AGENTS.md"

$AgentsMd = @"
# AGENTS.md

## Mission de l'agent

Tu aides l'utilisateur a comprendre, corriger, ameliorer et automatiser ses projets logiciels.
Tu dois etre prudent, pedagogique et orienté resultat.

## Regles de securite

- Ne jamais supprimer massivement des fichiers sans expliquer clairement le risque.
- Ne jamais modifier un environnement de production sans confirmation humaine.
- Ne jamais commit, push, deployer ou publier sans accord explicite.
- Ne jamais mettre de secrets, mots de passe, tokens ou cles API dans le code.
- Toujours preferer des changements petits, testables et reversibles.
- Toujours expliquer ce que tu vas changer avant un gros changement.

## Methode de travail

1. Comprendre le projet et lire les fichiers importants.
2. Proposer un plan court.
3. Modifier seulement ce qui est necessaire.
4. Lancer les tests ou checks disponibles.
5. Donner un resume clair:
   - fichiers modifies
   - probleme corrige
   - tests lances
   - prochaines actions recommandees

## Commandes usuelles a essayer selon le projet

### Python
- python --version
- python -m pip install -r requirements.txt
- python -m pytest
- black .
- isort .

### Node.js / React
- node --version
- npm install
- npm run lint
- npm run test
- npm run build

### Git
- git status
- git diff
- git log --oneline -5

## Style de reponse

- Repondre simplement.
- Eviter le jargon inutile.
- Donner des etapes actionnables.
- Signaler clairement les incertitudes.
"@

try {
    $AgentsMd | Out-File -FilePath $AgentPath -Encoding UTF8 -Force
    Write-Ok "AGENTS.md cree: $AgentPath"
    Add-Report "OK - AGENTS.md cree: $AgentPath"
} catch {
    Write-Warn2 "AGENTS.md non cree: $($_.Exception.Message)"
    Add-Report "WARN - AGENTS.md non cree: $($_.Exception.Message)"
}

# ============================================================
#  GUIDE CLIENT
# ============================================================
Write-Step "Creation du guide START_HERE"

$StartHere = @"
DEMARRAGE RAPIDE - CODEX CLIENT

1. Ouvre le raccourci sur le bureau:
   "Demarrer Codex"

2. Lors du premier lancement, Codex va demander une connexion.
   Connecte-toi avec ton compte ChatGPT ou une cle API OpenAI.

3. Mets ton projet dans ce dossier:
   $BootstrapRoot

4. Exemple de premiere demande a taper dans Codex:

   Analyse ce projet. Explique-moi ce qu'il fait, comment le lancer,
   quels fichiers sont importants, et propose un plan d'amelioration sans rien modifier.

5. Exemple pour corriger un probleme:

   Cherche pourquoi le projet ne se lance pas. Propose un plan,
   puis fais uniquement les changements necessaires. Lance les tests si disponibles.

6. Regle importante:
   Ne donne jamais a Codex tes mots de passe, tes cles API ou tes acces bancaires.
   Pour les projets sensibles, demande toujours validation avant modification.

Fichiers importants:
- Configuration Codex: $CodexConfig
- Instructions agent: $AgentPath
- Rapport installation: $ReportPath
"@

try {
    $StartHere | Out-File -FilePath $StartHerePath -Encoding UTF8 -Force
    Write-Ok "Guide client cree: $StartHerePath"
    Add-Report "OK - START_HERE cree."
} catch {
    Write-Warn2 "Guide non cree: $($_.Exception.Message)"
    Add-Report "WARN - START_HERE non cree: $($_.Exception.Message)"
}

# ============================================================
#  RACCOURCI BUREAU
# ============================================================
Write-Step "Creation du raccourci bureau"

$Desktop = [Environment]::GetFolderPath("Desktop")
$ShortcutPath = Join-Path $Desktop "Demarrer Codex.lnk"

$pwsh = Get-Command pwsh.exe -ErrorAction SilentlyContinue
if ($pwsh) {
    $shellExe = $pwsh.Source
} else {
    $shellExe = "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe"
}

$shortcutCommand = "-NoExit -Command `"Set-Location '$BootstrapRoot'; Write-Host 'Dossier Codex: $BootstrapRoot' -ForegroundColor Cyan; Write-Host 'Si Codex ne demarre pas automatiquement, tape: codex' -ForegroundColor Yellow; codex`""

Create-Shortcut `
    -ShortcutPath $ShortcutPath `
    -TargetPath $shellExe `
    -Arguments $shortcutCommand `
    -WorkingDirectory $BootstrapRoot `
    -Description "Ouvrir Codex dans le dossier client"

# ============================================================
#  VERIFICATIONS FINALES
# ============================================================
Write-Step "Verification finale"

$checks = @(
    @{ Cmd = "git"; Label = "Git" },
    @{ Cmd = "code"; Label = "VS Code" },
    @{ Cmd = "node"; Label = "Node.js" },
    @{ Cmd = "npm"; Label = "npm" },
    @{ Cmd = "python"; Label = "Python" },
    @{ Cmd = "gh"; Label = "GitHub CLI" },
    @{ Cmd = "codex"; Label = "Codex CLI" }
)

foreach ($check in $checks) {
    if (Test-CommandExists $check.Cmd) {
        try {
            $versionOutput = (& $check.Cmd --version 2>&1 | Select-Object -First 1)
            Write-Ok "$($check.Label): $versionOutput"
            Add-Report "OK - $($check.Label): $versionOutput"
        } catch {
            Write-Ok "$($check.Label): installe/detecte"
            Add-Report "OK - $($check.Label): detecte"
        }
    } else {
        Write-Warn2 "$($check.Label): non detecte dans cette session."
        Add-Report "WARN - $($check.Label): non detecte."
    }
}

Write-Step "Resultat"

if ($codexInstalled) {
    Write-Ok "Environnement pret. Le client peut ouvrir le raccourci 'Demarrer Codex'."
    Add-Report "RESULT - Environnement pret."
    exit 0
} else {
    Write-Warn2 "La base est installee, mais Codex CLI n'a pas ete detecte. Relance ce fichier apres redemarrage, ou lance: npm install -g @openai/codex@latest"
    Add-Report "RESULT - Codex CLI non detecte. Relance conseillee."
    exit 2
}
