"use strict";
const fs = require("fs");
const path = require("path");
const crypto = require("crypto");

const prefix = "VITE_APP_";
const RUNTIME_BASE_URL_PLACEHOLDER = "/@RUNTIME_BASE_URL@";
const APP_DIR = "./application";
const ENV_JS_DIR = APP_DIR;

function generateScriptContent() {
  const prefixRegex = new RegExp(`^${prefix}`);
  const env = process.env;
  const config = Object.keys(env)
    .filter(key => prefixRegex.test(key))
    .reduce((c, key) => Object.assign({}, c, { [key]: env[key] }), {});

  return `window.env=${JSON.stringify(config)};`;
}

function getSha256Hash(input) {
  const hash = crypto.createHash("sha256");
  hash.update(input);
  return hash.digest("hex");
}

function updateIndexHtml(envFileName, basePath) {
  const indexPath = path.join(APP_DIR, "index.html");

  if (!fs.existsSync(indexPath)) {
    console.error(`Error: ${indexPath} not found`);
    return;
  }

  let indexContent = fs.readFileSync(indexPath, "utf8");

  // Replace base path placeholder with actual value
  indexContent = indexContent.replace(new RegExp(RUNTIME_BASE_URL_PLACEHOLDER, "g"), basePath || "/");

  // Replace any existing env script with the new one
  const envScriptRegex = /<script src="[^"]*env(\.\w+)?\.js"[^>]*><\/script>/;
  const scriptSrc = basePath ? `${basePath.endsWith("/") ? basePath : basePath + "/"}${envFileName}` : envFileName;
  const newEnvScript = `<script src="${scriptSrc}"></script>`;

  if (envScriptRegex.test(indexContent)) {
    indexContent = indexContent.replace(envScriptRegex, newEnvScript);
  } else {
    // If no existing env script, add it before the first script tag
    const insertPoint = indexContent.indexOf("<script");
    if (insertPoint !== -1) {
      indexContent =
        indexContent.substring(0, insertPoint) + newEnvScript + "\n    " + indexContent.substring(insertPoint);
    }
  }

  fs.writeFileSync(indexPath, indexContent, "utf8");
  console.log(`Updated ${indexPath} with base path: ${basePath || "/"} and env script: ${scriptSrc}`);
}

function cleanupOldEnvFiles(newEnvFileName) {
  // Find all env*.js files and delete them except the new one
  const files = fs.readdirSync(ENV_JS_DIR);
  const envFiles = files.filter(file => /^env(\.\w+)?\.js$/.test(file) && file !== newEnvFileName);

  for (const file of envFiles) {
    const filePath = path.join(ENV_JS_DIR, file);
    fs.unlinkSync(filePath);
    console.log(`Removed old env file: ${filePath}`);
  }
}

function main() {
  console.log("Setting environment variables...");

  // Generate env script content
  const scriptContent = generateScriptContent();

  // Compute hash for cache busting
  const hash = getSha256Hash(scriptContent);
  const fragment = hash.substring(0, 8);
  const envFileName = `env.${fragment}.js`;
  const envFilePath = path.join(ENV_JS_DIR, envFileName);

  // Ensure build directory exists
  if (!fs.existsSync(APP_DIR)) {
    console.log(`Creating build directory: ${APP_DIR}`);
    fs.mkdirSync(APP_DIR, { recursive: true });
  }

  // Write new env.js file
  fs.writeFileSync(envFilePath, scriptContent, "utf8");
  console.log(`Updated ${envFilePath} with ${prefix}* environment variables`);

  // Clean up old env.js files
  cleanupOldEnvFiles(envFileName);

  // Get base path from environment and update index.html
  const basePath = process.env.VITE_APP_BASE_URL || "/";
  updateIndexHtml(envFileName, basePath);
}

main();
