#!/usr/bin/env node

/**
 * Version info generation script
 * Generates version file with version, build date, Git info at build time
 */

const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const {
  printSuccess,
  printInfo,
  printWarning,
  colors,
  colorize,
} = require('./console-style.cjs');

const packageJsonPath = path.resolve(__dirname, '../package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));

function parseBuildEnv(args) {
  const index = args.indexOf('--build-env');
  const buildEnv = index >= 0 ? args[index + 1] : undefined;
  if (!['development', 'production', 'preview'].includes(buildEnv)) {
    throw new Error('Expected --build-env development|production|preview');
  }
  return buildEnv;
}

function readArg(args, name) {
  const index = args.indexOf(name);
  return index >= 0 ? args[index + 1] : undefined;
}

function getGitInfo() {
  try {
    const gitCommitFull = execSync('git rev-parse HEAD', { encoding: 'utf-8' }).trim();
    const gitCommit = gitCommitFull.substring(0, 7);
    const gitBranch = execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf-8' }).trim();
    
    return {
      gitCommit,
      gitCommitFull,
      gitBranch
    };
  } catch (error) {
    printWarning('Could not get Git info (may not be a Git repo)');
    return {
      gitCommit: undefined,
      gitCommitFull: undefined,
      gitBranch: undefined
    };
  }
}

function generateVersionInfo(buildEnv) {
  const gitInfo = getGitInfo();
  const buildDate = new Date().toISOString();
  const buildTimestamp = Date.now();
  const isDev = buildEnv === 'development';
  const releaseChannel = process.env.BITFUN_RELEASE_CHANNEL || 'stable';
  if (!['stable', 'beta', 'nightly'].includes(releaseChannel)) {
    throw new Error(`Unsupported BITFUN_RELEASE_CHANNEL: ${releaseChannel}`);
  }
  
  const versionInfo = {
    name: packageJson.name === 'BitFun' ? 'BitFun' : packageJson.name,
    version: packageJson.version,
    buildDate,
    buildTimestamp,
    buildEnv,
    releaseChannel,
    isDev,
    ...gitInfo
  };
  
  return versionInfo;
}

function saveVersionInfoToJson(versionInfo, outputRoot) {
  const outputPath = path.resolve(outputRoot, 'src/web-ui/public/version.json');
  
  const dir = path.dirname(outputPath);
  if (!fs.existsSync(dir)) {
    fs.mkdirSync(dir, { recursive: true });
  }
  
  fs.writeFileSync(
    outputPath,
    JSON.stringify(versionInfo, null, 2),
    'utf-8'
  );
}

function saveVersionInfoToTS(versionInfo, outputRoot) {
  const outputPath = path.resolve(outputRoot, 'src/web-ui/src/generated/version.ts');
  
  const dir = path.dirname(outputPath);
  if (!fs.existsSync(dir)) {
    fs.mkdirSync(dir, { recursive: true });
  }
  
  const content = `/**
 * Auto-generated version info. Do not edit.
 * Generated: ${new Date().toISOString()}
 */

import type { VersionInfo } from '../shared/types/version';

export const VERSION_INFO: VersionInfo = ${JSON.stringify(versionInfo, null, 2)};
`;
  
  fs.writeFileSync(outputPath, content, 'utf-8');
}

function generateHtmlInjectionScript(versionInfo) {
  return `<script>
  // Version info injected at build time
  window.__VERSION_INFO__ = ${JSON.stringify(versionInfo)};
</script>`;
}

function main() {
  const args = process.argv.slice(2);
  const buildEnv = parseBuildEnv(args);
  const outputRoot = path.resolve(readArg(args, '--output-root') || path.resolve(__dirname, '..'));
  const versionInfo = generateVersionInfo(buildEnv);
  
  saveVersionInfoToJson(versionInfo, outputRoot);
  saveVersionInfoToTS(versionInfo, outputRoot);
  
  const htmlScript = generateHtmlInjectionScript(versionInfo);
  const htmlScriptPath = path.resolve(outputRoot, 'src/web-ui/src/generated/version-injection.html');
  
  const htmlDir = path.dirname(htmlScriptPath);
  if (!fs.existsSync(htmlDir)) {
    fs.mkdirSync(htmlDir, { recursive: true });
  }
  
  fs.writeFileSync(htmlScriptPath, htmlScript, 'utf-8');
  
  const gitStr = versionInfo.gitCommit ? ` ${versionInfo.gitBranch}@${versionInfo.gitCommit}` : '';
  printSuccess(`${versionInfo.name} v${versionInfo.version}${gitStr}`);
}

try {
  main();
} catch (err) {
  printWarning('Version info generation failed: ' + (err.message || err));
  process.exit(1);
}