/**
 * Function/Windows/startup-manager.js
 * ---------------------------------------------------------------------------
 * STARTUP PROGRAMS
 *
 * Everything Windows launches at sign-in: registry Run keys, the Startup
 * folders and scheduled tasks that trigger at logon. Informational - this
 * module reports what starts, it does not disable entries.
 * ---------------------------------------------------------------------------
 */

'use strict';

const kit = require('../../core/kit');
const system = require('../../core/system');

const QUERY = [
  '$ErrorActionPreference = "SilentlyContinue"',
  'function SafeGet([scriptblock] $block) { try { & $block } catch { $null } }',
  '$wmi = SafeGet { @(Get-CimInstance Win32_StartupCommand -ErrorAction Stop | Select-Object Name, Command, Location, User) }',
  '$folders = SafeGet {',
  '  $paths = @(',
  '    (Join-Path $env:APPDATA "Microsoft\\Windows\\Start Menu\\Programs\\Startup"),',
  '    (Join-Path $env:ProgramData "Microsoft\\Windows\\Start Menu\\Programs\\Startup")',
  '  )',
  '  @(Get-ChildItem -Path $paths -File -ErrorAction SilentlyContinue | Select-Object Name, FullName, Length, LastWriteTime)',
  '}',
  '$tasks = SafeGet {',
  '  @(Get-ScheduledTask -ErrorAction Stop |',
  '    Where-Object { $_.State -ne "Disabled" -and ($_.Triggers | Where-Object { $_.CimClass.CimClassName -eq "MSFT_TaskLogonTrigger" -or $_.CimClass.CimClassName -eq "MSFT_TaskBootTrigger" }) } |',
  '    Select-Object TaskName, TaskPath, State, Author)',
  '}',
  '[ordered]@{ wmi = @($wmi); folders = @($folders); tasks = @($tasks) } | ConvertTo-Json -Depth 4 -Compress',
].join('\n');

async function collect() {
  const result = await system.runPowerShellJson(QUERY, { timeoutMs: 120000 });
  if (!result.ok || !result.data) return null;
  return {
    registry: system.asArray(result.data.wmi),
    folders: system.asArray(result.data.folders),
    tasks: system.asArray(result.data.tasks),
  };
}

/** Executable out of a command line, without the arguments. */
function executableOf(command) {
  const text = String(command || '').trim();
  const quoted = text.match(/^"([^"]+)"/);
  if (quoted) return quoted[1];
  const first = text.split(/\s+/)[0];
  return first || text;
}

module.exports = {
  name: 'Startup Programs',
  menuName: 'Startup Manager',
  description: 'Programs and tasks Windows starts at sign-in, from the registry, folders and scheduler.',
  version: '1.0.0',
  author: 'InfinitySniper HFX',
  category: 'Windows',
  order: 50,
  requiredPermissions: 'normal',
  destructive: false,
  dependencies: [],
  minimumAppVersion: '1.0.0',
  permissions: ['system:read', 'wmi:query', 'registry:read', 'filesystem:read'],
  tags: ['startup', 'autostart', 'boot', 'logon', 'tasks'],
  documentation:
    'Collects everything that launches automatically: the Run and RunOnce registry keys (per user ' +
    'and machine-wide), the user and common Startup folders, and the scheduled tasks that trigger ' +
    'at logon or boot. Each entry shows the command and where it comes from, so a slow sign-in can ' +
    'be traced. Disabling an entry is deliberately not offered here - use Task Manager > Startup, ' +
    'which is the supported way and keeps Windows in a consistent state.',

  async selfTest(ctx) {
    if (!ctx.system.IS_WINDOWS) return { ok: false, message: 'Windows only' };
    const data = await collect();
    if (!data) return { ok: false, message: 'startup query failed' };
    return { ok: true, message: `${data.registry.length + data.folders.length} startup entry/entries` };
  },

  async execute(ctx) {
    const { ui, prompt } = ctx;
    kit.header('Startup Manager', ['What Windows launches when you sign in.']);
    if (!kit.requireWindows('The startup manager')) return { ok: false, reason: 'unsupported-platform' };

    const spin = ui.spinner('Reading startup entries...');
    const data = await collect();
    spin.stop();
    if (!data) return kit.noData('startup information');

    const total = data.registry.length + data.folders.length;

    ui.section('SUMMARY');
    ui.blank();
    kit.kv('Registry Entries', system.formatNumber(data.registry.length));
    kit.kv('Startup Folder Items', system.formatNumber(data.folders.length));
    kit.kv('Logon / Boot Tasks', system.formatNumber(data.tasks.length));
    kit.kv('Total Autostart Items', system.formatNumber(total + data.tasks.length), total > 20 ? 'brightYellow' : 'brightWhite');

    ui.blank();
    ui.section('REGISTRY AND FOLDER ENTRIES');
    ui.blank();
    if (!data.registry.length && !data.folders.length) {
      ui.println('  ' + ui.c.gray('Nothing starts from the registry or the Startup folders.'));
    } else {
      kit.table(
        ['NAME', 'COMMAND', 'SOURCE'],
        [
          ...data.registry.map((entry) => [
            ui.c.brightWhite(ui.truncate(system.clean(entry.Name) || '-', 24)),
            ui.c.gray(ui.truncate(executableOf(entry.Command), 30)),
            ui.c.brightCyan(ui.truncate(system.clean(entry.Location) || '-', 18)),
          ]),
          ...data.folders.map((entry) => [
            ui.c.brightWhite(ui.truncate(system.clean(entry.Name) || '-', 24)),
            ui.c.gray(ui.truncate(system.clean(entry.FullName) || '-', 30)),
            ui.c.brightCyan('Startup folder'),
          ]),
        ],
        { limit: 25 }
      );
    }

    if (data.tasks.length) {
      ui.blank();
      ui.section('SCHEDULED TASKS AT LOGON OR BOOT');
      ui.blank();
      kit.table(
        ['TASK', 'PATH', 'STATE'],
        data.tasks.map((task) => [
          ui.c.brightWhite(ui.truncate(system.clean(task.TaskName) || '-', 30)),
          ui.c.gray(ui.truncate(system.clean(task.TaskPath) || '-', 24)),
          String(task.State) === 'Ready' ? ui.c.brightGreen(String(task.State)) : ui.c.gray(String(task.State)),
        ]),
        { limit: 20 }
      );
    }

    ui.blank();
    if (total > 20) {
      ui.warning('Many programs start automatically - this is the usual reason for a slow sign-in.');
    }
    ui.println('  ' + ui.c.gray('Disable entries in Task Manager > Startup; this tool only reports them.'));

    await kit.offerExport('Startup Programs Report', 'StartupPrograms', (report) => {
      const section = report.section('SUMMARY');
      section.add('Registry Entries', system.formatNumber(data.registry.length));
      section.add('Startup Folder Items', system.formatNumber(data.folders.length));
      section.add('Logon / Boot Tasks', system.formatNumber(data.tasks.length));

      const registry = report.section('REGISTRY ENTRIES');
      data.registry.forEach((entry, index) => {
        const group = registry.group(`${index + 1}. ${system.clean(entry.Name) || 'Unnamed'}`);
        group.add('Command', system.clean(entry.Command));
        group.add('Location', system.clean(entry.Location));
        group.add('User', system.clean(entry.User));
      });

      const folders = report.section('STARTUP FOLDER ITEMS');
      data.folders.forEach((entry, index) => {
        folders.add(`${index + 1}. ${system.clean(entry.Name)}`, system.clean(entry.FullName));
      });

      const tasks = report.section('SCHEDULED TASKS');
      data.tasks.forEach((task, index) => {
        tasks.add(`${index + 1}. ${system.clean(task.TaskName)}`, `${system.clean(task.TaskPath) || ''} (${task.State})`);
      });
    });

    return kit.done('Startup information collected.');
  },
};
