import path from "path";
import fs from "fs";
import JavaScriptObfuscator from 'javascript-obfuscator';
import {
  renamePackageJsonName,
  createEnvFile,
  createGitIgnoreFile,
  copyTemplateFiles,
  updatePackageJsonEngine,
  copyWorkflowFile,
} from "./boilerplateHelper";
import { APItype, CItype, GUItype, Platformtype, Project } from "../models/models";
import { convertToValidPackageName } from "../prompts/prompts";
import { LOCAL_BASE_URL, PROD_BASE_URL, STAGING_BASE_URL } from "../config/axios.config";

export type Environment = "staging" | "production" | "local";
const obfuscationOptions = {
  compact: true,
  controlFlowFlattening: true,
  controlFlowFlatteningThreshold: 0.75,
  numbersToExpressions: true,
  simplify: true,
  stringArrayShuffle: true,
  splitStrings: true,
  stringArrayThreshold: 0.8
};

async function createStandardBoilerplateUI(
  appPath: string,
  project: Project,
  includeSampleTest: boolean,
  token: string,
  needGitActionSetup: boolean,
  environment: Environment = "staging",
  platform: Platformtype
) {
  let baseURL = PROD_BASE_URL;
  if (environment == "local")
    baseURL = LOCAL_BASE_URL;
  else if (environment == "staging")
    baseURL = STAGING_BASE_URL;
  let platformtype;
  switch(platform){
    case Platformtype.Cypress:
      platformtype = "cypress";
      break;
    case Platformtype.Playwright:
      platformtype = "playwright";
      break;
  }
  const templateDir = path.join(__dirname, `../../templates/standard/${platformtype}/ui`);
  const commonTemplateDir = path.join(__dirname, `../../templates/standard/common`);
  const frameworkCommonTemplateDir = path.join(__dirname, `../../templates/standard/${platformtype}/common`);
  copyTemplateFiles(
    templateDir,
    appPath,
    includeSampleTest,
    baseURL
  );
  copyTemplateFiles(
    commonTemplateDir,
    appPath,
    includeSampleTest,
    baseURL
  );
  copyTemplateFiles(
    frameworkCommonTemplateDir,
    appPath,
    includeSampleTest,
    baseURL
  );
  if(needGitActionSetup)
    copyWorkflowFile(appPath, platformtype, project.repositoryType, baseURL);
  renamePackageJsonName(appPath, convertToValidPackageName(project.name));
  updatePackageJsonEngine(appPath, environment, platform);
  createEnvFile(appPath, token, project.id, environment == "production" ? '' : baseURL);
  createGitIgnoreFile(appPath);
  copyInitializeFile(appPath, baseURL, platformtype);
}

async function createStandardBoilerplateAPI(
  appPath: string,
  project: Project,
  includeSampleTest: boolean,
  token: string,
  needGitActionSetup: boolean,
  environment: Environment = "staging",
  platform: Platformtype
) {
  let baseURL = PROD_BASE_URL;
  if (environment == "local")
    baseURL = LOCAL_BASE_URL;
  else if (environment == "staging")
    baseURL = STAGING_BASE_URL;
  let platformtype;
  switch(platform){
    case Platformtype.Cypress:
      platformtype = "cypress";
      break;
    case Platformtype.Playwright:
      platformtype = "playwright";
      break;
  }
  const templateDir = path.join(__dirname, `../../templates/standard/${platformtype}/api`);
  const commonTemplateDir = path.join(__dirname, `../../templates/standard/common`);
  const frameworkCommonTemplateDir = path.join(__dirname, `../../templates/standard/${platformtype}/common`);
  copyTemplateFiles(
    templateDir,
    appPath,
    includeSampleTest,
    baseURL
  );
  copyTemplateFiles(
    commonTemplateDir,
    appPath,
    includeSampleTest,
    baseURL
  );
  copyTemplateFiles(
    frameworkCommonTemplateDir,
    appPath,
    includeSampleTest,
    baseURL
  );
  if(needGitActionSetup)
    copyWorkflowFile(appPath, platformtype, project.repositoryType, baseURL);
  renamePackageJsonName(appPath, convertToValidPackageName(project.name));
  updatePackageJsonEngine(appPath, environment, platform);
  createEnvFile(appPath, token, project.id, environment == "production" ? '' : baseURL);
  createGitIgnoreFile(appPath);
  copyInitializeFile(appPath, baseURL, platformtype);
}

const copyInitializeFile = (appPath: string, baseURL: string, platformtype: string) => {
  let sourceFileName = "ordino.initialize.js";
  const sourceFile = path.join(
    __dirname,
    `../../templates/initializers/${platformtype}/${sourceFileName}`
  );
  const targetFile = path.join(appPath, "ordino.initialize.js");
  let fileContent = fs.readFileSync(sourceFile, { encoding: 'utf8' });
        fileContent = fileContent.replace("{{OrdinoURL}}", baseURL);
  const obfuscationResult = JavaScriptObfuscator.obfuscate(
    fileContent,
    obfuscationOptions
  );
  const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
  fs.writeFileSync(targetFile, obfuscatedCode);
};

export {
  createStandardBoilerplateUI,
  createStandardBoilerplateAPI
};

