import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const DEFAULT_CONFIG_DIRNAME = '.alga-psa-appliance';

function exists(filePath) {
  try {
    fs.accessSync(filePath, fs.constants.R_OK);
    return true;
  } catch {
    return false;
  }
}

function isDirectory(filePath) {
  try {
    return fs.statSync(filePath).isDirectory();
  } catch {
    return false;
  }
}

function walkUpForRepo(startDir) {
  let cursor = path.resolve(startDir);
  while (true) {
    const candidate = path.join(cursor, 'ee', 'appliance', 'scripts', 'collect-support-bundle.sh');
    if (exists(candidate)) {
      return cursor;
    }
    const parent = path.dirname(cursor);
    if (parent === cursor) {
      return null;
    }
    cursor = parent;
  }
}

export function resolveRuntimePaths(options = {}) {
  const assetRoot =
    options.assetRoot ||
    process.env.ALGA_APPLIANCE_ASSET_ROOT ||
    null;

  if (assetRoot) {
    return {
      runtimeMode: 'asset-root',
      assetRoot: path.resolve(assetRoot),
      scriptsDir: path.resolve(assetRoot, 'scripts'),
      fluxDir: path.resolve(assetRoot, 'flux'),
      supportBundleScript: path.resolve(assetRoot, 'scripts', 'collect-support-bundle.sh'),
      repairScript: path.resolve(assetRoot, 'scripts', 'repair-release.sh'),
      resetScript: path.resolve(assetRoot, 'scripts', 'reset-appliance-data.sh'),
    };
  }

  const base =
    walkUpForRepo(options.cwd || process.cwd()) ||
    walkUpForRepo(path.dirname(fileURLToPath(import.meta.url)));

  if (!base) {
    throw new Error('Unable to resolve appliance runtime paths. Set ALGA_APPLIANCE_ASSET_ROOT.');
  }

  return {
    runtimeMode: 'repo',
    repoRoot: base,
    assetRoot: path.join(base, 'ee', 'appliance'),
    scriptsDir: path.join(base, 'ee', 'appliance', 'scripts'),
    fluxDir: path.join(base, 'ee', 'appliance', 'flux'),
    supportBundleScript: path.join(base, 'ee', 'appliance', 'scripts', 'collect-support-bundle.sh'),
    repairScript: path.join(base, 'ee', 'appliance', 'scripts', 'repair-release.sh'),
    resetScript: path.join(base, 'ee', 'appliance', 'scripts', 'reset-appliance-data.sh'),
  };
}

export function resolveConfigBase(homeDir) {
  const explicitRoot = process.env.ALGA_APPLIANCE_HOME;
  if (explicitRoot) {
    return path.resolve(explicitRoot);
  }

  return path.join(homeDir, DEFAULT_CONFIG_DIRNAME);
}

export function listSiteIds(configBaseDir) {
  if (!isDirectory(configBaseDir)) {
    return [];
  }
  return fs
    .readdirSync(configBaseDir, { withFileTypes: true })
    .filter((entry) => entry.isDirectory())
    .map((entry) => entry.name)
    .sort();
}

export function resolveSitePaths(configBaseDir, siteId) {
  const dir = path.join(configBaseDir, siteId);
  return {
    siteId,
    configDir: dir,
    kubeconfig: path.join(dir, 'kubeconfig'),
    talosconfig: path.join(dir, 'talosconfig'),
    nodeIpFile: path.join(dir, 'node-ip'),
    appUrlFile: path.join(dir, 'app-url'),
  };
}

export function fileExists(filePath) {
  return exists(filePath);
}
