// cross-platform-paths.mjs — Cache/Log/State/Backup dir resolution per OS.
// Zero dependencies. macOS uses ~/Library/{Caches,Logs,Application Support},
// Linux uses XDG with fallbacks, Windows uses %LOCALAPPDATA%.

import { mkdirSync } from 'node:fs';
import { homedir as osHomedir, platform as osPlatform } from 'node:os';
import { join } from 'node:path';

function resolveOpts(opts = {}) {
  return {
    platform: opts.platform ?? osPlatform(),
    homedir: opts.homedir ?? osHomedir,
    env: opts.env ?? process.env,
  };
}

function ensureDir(path) {
  mkdirSync(path, { recursive: true });
  return path;
}

function requireApp(appName) {
  if (!appName || typeof appName !== 'string') {
    throw new Error('cross-platform-paths: appName is required and must be a non-empty string');
  }
}

/**
 * Resolve a per-app cache directory.
 * @param {string} appName — application identifier, e.g. "ms-ai-architect"
 * @param {object} [opts] — { platform, homedir, env } for testing
 * @returns {string} absolute path to the cache directory (created if missing)
 */
export function getCacheDir(appName, opts) {
  requireApp(appName);
  const { platform, homedir, env } = resolveOpts(opts);
  const home = homedir();

  if (platform === 'darwin') {
    return ensureDir(join(home, 'Library', 'Caches', appName));
  }
  if (platform === 'win32') {
    const lad = env.LOCALAPPDATA || join(home, 'AppData', 'Local');
    return ensureDir(join(lad, appName, 'Cache'));
  }
  // linux + everything else
  const xdg = env.XDG_CACHE_HOME || join(home, '.cache');
  return ensureDir(join(xdg, appName));
}

/**
 * Resolve a per-app log directory.
 * @param {string} appName
 * @param {object} [opts]
 * @returns {string} absolute path to the log directory (created if missing)
 */
export function getLogDir(appName, opts) {
  requireApp(appName);
  const { platform, homedir, env } = resolveOpts(opts);
  const home = homedir();

  if (platform === 'darwin') {
    return ensureDir(join(home, 'Library', 'Logs', appName));
  }
  if (platform === 'win32') {
    const lad = env.LOCALAPPDATA || join(home, 'AppData', 'Local');
    return ensureDir(join(lad, appName, 'Logs'));
  }
  const xdg = env.XDG_STATE_HOME || join(home, '.local', 'state');
  return ensureDir(join(xdg, appName, 'logs'));
}

/**
 * Resolve a per-app state/data directory (persistent app state, not cache).
 * @param {string} appName
 * @param {object} [opts]
 * @returns {string} absolute path (created if missing)
 */
export function getStateDir(appName, opts) {
  requireApp(appName);
  const { platform, homedir, env } = resolveOpts(opts);
  const home = homedir();

  if (platform === 'darwin') {
    return ensureDir(join(home, 'Library', 'Application Support', appName));
  }
  if (platform === 'win32') {
    const lad = env.LOCALAPPDATA || join(home, 'AppData', 'Local');
    return ensureDir(join(lad, appName, 'State'));
  }
  const xdg = env.XDG_STATE_HOME || join(home, '.local', 'state');
  return ensureDir(join(xdg, appName));
}

/**
 * Resolve the backup directory under a plugin root.
 * @param {string} pluginRoot — absolute path to the plugin root
 * @returns {string} absolute path to <pluginRoot>/.kb-backup (created if missing)
 */
export function getBackupDir(pluginRoot) {
  if (!pluginRoot || typeof pluginRoot !== 'string') {
    throw new Error('cross-platform-paths: pluginRoot is required and must be a non-empty string');
  }
  return ensureDir(join(pluginRoot, '.kb-backup'));
}
