/**
 * routes/apppools.js
 * IIS Application Pool management via PowerShell WebAdministration.
 * Mount at /api/apppools in server.js.
 */
const express      = require('express');
const { execSync } = require('child_process');
const router       = express.Router();
const authMw       = require('../middleware/auth');
const { writeAudit } = require('./audit');

const ps = (cmd, timeout = 30000) =>
  execSync(`powershell -ExecutionPolicy Bypass -Command "${cmd}"`, { timeout }).toString().trim();

// ── List all app pools (cached) ───────────────────────────
router.get('/', authMw, (req, res) => {
  sCache('apppools', 15000, () => {
    const raw = ps(`
      Import-Module WebAdministration;
      Get-ChildItem IIS:\\AppPools | ForEach-Object {
        $pool = $_;
        [PSCustomObject]@{
          name            = $pool.Name
          state           = $pool.State.ToString()
          dotNetVersion   = $pool.managedRuntimeVersion
          pipelineMode    = $pool.managedPipelineMode.ToString()
          enable32Bit     = $pool.enable32BitAppOnWin64
          autoStart       = $pool.autoStart
          workerProcesses = @(Get-WebConfiguration /system.applicationHost/applicationPools/add[@name='$($pool.Name)']/workerProcesses/* 2>$null).Count
          queueLength     = $pool.queueLength
        }
      } | ConvertTo-Json -Depth 2
    `);
    if (!raw) return [];
    const list = JSON.parse(raw);
    return Array.isArray(list) ? list : [list];
  }).then(data => res.json(data))
    .catch(e => res.status(500).json({ error: e.message }));
});

// ── Create app pool ───────────────────────────────────────
router.post('/', authMw, (req, res) => {
  const { name, dotNetVersion, pipelineMode, enable32Bit } = req.body;
  if (!name) return res.status(400).json({ error: 'Pool name is required' });
  if (!/^[\w\-. ]+$/.test(name)) return res.status(400).json({ error: 'Invalid pool name' });
  try {
    const ver  = dotNetVersion || 'v4.0';
    const mode = pipelineMode  || 'Integrated';
    const e32  = enable32Bit   ? '$true' : '$false';
    ps(`
      Import-Module WebAdministration;
      New-WebAppPool -Name '${name}';
      Set-ItemProperty IIS:\\AppPools\\${name} managedRuntimeVersion '${ver}';
      Set-ItemProperty IIS:\\AppPools\\${name} managedPipelineMode '${mode}';
      Set-ItemProperty IIS:\\AppPools\\${name} enable32BitAppOnWin64 ${e32};
    `);
    writeAudit(req, 'apppools.create', `Created app pool "${name}" (${ver}, ${mode})`);
    sCacheClear('apppools');
    res.json({ ok: true });
  } catch (e) { res.status(500).json({ error: e.message }); }
});

// ── Update app pool settings ──────────────────────────────
router.put('/:name', authMw, (req, res) => {
  const { name } = req.params;
  const { dotNetVersion, pipelineMode, enable32Bit, queueLength } = req.body;
  try {
    if (dotNetVersion !== undefined)
      ps(`Import-Module WebAdministration; Set-ItemProperty IIS:\\AppPools\\${name} managedRuntimeVersion '${dotNetVersion}'`);
    if (pipelineMode !== undefined)
      ps(`Import-Module WebAdministration; Set-ItemProperty IIS:\\AppPools\\${name} managedPipelineMode '${pipelineMode}'`);
    if (enable32Bit !== undefined)
      ps(`Import-Module WebAdministration; Set-ItemProperty IIS:\\AppPools\\${name} enable32BitAppOnWin64 ${enable32Bit ? '$true' : '$false'}`);
    if (queueLength !== undefined)
      ps(`Import-Module WebAdministration; Set-ItemProperty IIS:\\AppPools\\${name} queueLength ${parseInt(queueLength)}`);
    writeAudit(req, 'apppools.update', `Updated app pool "${name}"`);
    sCacheClear('apppools');
    res.json({ ok: true });
  } catch (e) { res.status(500).json({ error: e.message }); }
});

// ── Start ─────────────────────────────────────────────────
router.post('/:name/start', authMw, (req, res) => {
  try {
    ps(`Import-Module WebAdministration; Start-WebAppPool -Name '${req.params.name}'`);
    writeAudit(req, 'apppools.start', `Started app pool "${req.params.name}"`);
    sCacheClear('apppools');
    res.json({ ok: true });
  } catch (e) { res.status(500).json({ error: e.message }); }
});

// ── Stop ──────────────────────────────────────────────────
router.post('/:name/stop', authMw, (req, res) => {
  try {
    ps(`Import-Module WebAdministration; Stop-WebAppPool -Name '${req.params.name}'`);
    writeAudit(req, 'apppools.stop', `Stopped app pool "${req.params.name}"`);
    sCacheClear('apppools');
    res.json({ ok: true });
  } catch (e) { res.status(500).json({ error: e.message }); }
});

// ── Recycle ───────────────────────────────────────────────
router.post('/:name/recycle', authMw, (req, res) => {
  try {
    ps(`Import-Module WebAdministration; Restart-WebAppPool -Name '${req.params.name}'`);
    writeAudit(req, 'apppools.recycle', `Recycled app pool "${req.params.name}"`);
    sCacheClear('apppools');
    res.json({ ok: true });
  } catch (e) { res.status(500).json({ error: e.message }); }
});

// ── Delete ────────────────────────────────────────────────
router.delete('/:name', authMw, (req, res) => {
  try {
    ps(`Import-Module WebAdministration; Remove-WebAppPool -Name '${req.params.name}'`);
    writeAudit(req, 'apppools.delete', `Deleted app pool "${req.params.name}"`);
    sCacheClear('apppools');
    res.json({ ok: true });
  } catch (e) { res.status(500).json({ error: e.message }); }
});

// ── Get sites using a pool ────────────────────────────────
router.get('/:name/sites', authMw, (req, res) => {
  try {
    const raw = ps(`
      Import-Module WebAdministration;
      Get-Website | Where-Object { $_.applicationPool -eq '${req.params.name}' } |
      Select-Object Name, State, @{N='Binding';E={($_.Bindings.Collection[0]).bindingInformation}} |
      ConvertTo-Json
    `);
    if (!raw) return res.json([]);
    const list = JSON.parse(raw);
    res.json(Array.isArray(list) ? list : [list]);
  } catch (e) { res.status(500).json({ error: e.message }); }
});

module.exports = router;