const log = (text) => {
  console.log(` \u001b[32m${text}\u001b[0m`);
};

log("Start sync-docs.js");

const childProcess = require("child_process");
const fs = require("fs");
const path = require("path");
const common = require("./common.js");

const { projects, languages, projectPaths } = common;

const isFileExisted = (path) => {
  return fs.existsSync(path);
};

const replaceMDElements = (project, path, branch = "master") => {
  const replace = require("replace-in-file");
  const allMDFilePaths = path.map((p) => `${p}/**/*.md`);

  // replace the image urls inside markdown files
  const imageOptions = {
    files: allMDFilePaths,
    // NOTE: just replace the url begin with ../assets/images ,then can replace with absolute url path
    from: /(\.\.\/)+assets\/images\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/g,
    to: (match) => {
      const imgPath = match.replace(/\(|\)|\.\.\/*/g, "");
      const newUrl = `https://raw.githubusercontent.com/apache/${project}/${branch}/docs/${imgPath}`;
      console.log(`${project}: ${match} 👉 ${newUrl}`);
      return newUrl;
    },
  };

  // replace the markdown urls inside markdown files
  const markdownOptions = {
    files: allMDFilePaths,
    from: RegExp(
      `\\[.*\\]\\((\\.\\.\\/)*(${languages.join("|")})\\/.*\\.md\\)`,
      "g"
    ),
    to: (match) => {
      const markdownPath = match.replace(/\(|\)|\.\.\/*|\[.*\]|\.\//g, ""); // "en/latest/discovery/dns.md"
      const lang = markdownPath.split("/")[0];
      const urlPath = markdownPath.replace(
        RegExp(`(${languages.join("|")})\\/latest\\/|\\.md`, "g"),
        ""
      ); // "discovery/dns"
      const projectNameWithoutPrefix =
        project === "apisix" ? "apisix" : project.replace("apisix-", "");
      let newUrl = match.replace(
        /\]\(.*\)/g,
        `](https://apisix.apache.org${lang !== "en" ? "/" + lang : ""
        }/docs/${projectNameWithoutPrefix}/${urlPath})`
      );
      log(`${project}: ${match} 👉 ${newUrl}`);
      return newUrl;
    },
  };

  try {
    replace.sync(imageOptions);
    replace.sync(markdownOptions);
  } catch (error) {
    console.error(`${project} - Error occurred:`, error);
  }
};

const removeFolder = (tarDir) => {
  if (!fs.existsSync(tarDir)) return;

  let files = fs.readdirSync(tarDir);
  files.forEach((file) => {
    const tarPath = path.join(tarDir, file);
    let stats = fs.statSync(tarPath);
    if (stats.isDirectory()) {
      removeFolder(tarPath);
    } else {
      fs.unlinkSync(tarPath);
    }
  });

  fs.rmdirSync(tarDir);
};

const copyFolder = (srcDir, tarDir) => {
  let files = fs.readdirSync(srcDir);
  if (isFileExisted(tarDir) === false) {
    fs.mkdirSync(tarDir, () => log(`create directory ${tarDir}`));
  }
  files.forEach((file) => {
    let srcPath = path.join(srcDir, file);
    let tarPath = path.join(tarDir, file);

    let stats = fs.statSync(srcPath);
    if (stats.isDirectory()) {
      if (!fs.existsSync(tarPath)) {
        fs.mkdirSync(tarPath);
      }
      copyFolder(srcPath, tarPath);
    } else {
      fs.copyFileSync(srcPath, tarPath);
    }
  });
};

const copyDocs = (source, target, projectName, locale) => {
  if (isFileExisted(`${source}/${locale}/latest`) === false) {
    log(`[${projectName}] can not find ${locale} latest folder, skip.`);
    return;
  }

  log(`[${projectName}] load ${locale} latest docs config.json`);
  const configLatest = JSON.parse(
    fs.readFileSync(`${source}/${locale}/latest/config.json`)
  );

  log(`[${projectName}] delete ${locale} docs config.json`);
  fs.unlinkSync(`${source}/${locale}/latest/config.json`);

  log(`[${projectName}] copy latest ${locale} docs to ${target}`);
  copyFolder(`${source}/${locale}/latest/`, target);

  log(`[${projectName}] write sidebar.json`);
  const sidebar = {
    docs: [...(configLatest.sidebar || [])],
  };
  fs.writeFileSync(`${target}/sidebars.json`, JSON.stringify(sidebar, null, 2));
};

const copyAllDocs = (project) => {
  copyDocs(
    `./tmp/${project.name}/docs`,
    project.latestDocs.en,
    project.name,
    "en"
  );
  copyDocs(
    `./tmp/${project.name}/docs`,
    project.latestDocs.zh,
    project.name,
    "zh"
  );
};

const cloneRepos = () => {
  log("Clone repos");
  const gitCommand = projects
    .map((project) => `git clone https://github.com/apache/${project.name}.git`)
    .join(" & ");
  childProcess.execSync(gitCommand, { cwd: "./tmp" });
};

const findReleaseVersions = (project) => {
  // release branch name format example: origin/release/2.5
  const branchRaw = childProcess
    .execSync("git --no-pager branch -r", {
      cwd: `./tmp/${project}`,
    })
    .toString();
  const versions = [];
  branchRaw.split("\n").map((b) => {
    if (b.includes("release/") === false) return;
    const version = b.trim().replace("origin/release/", "");
    if (version === "test") return;
    versions.push(version);
  });
  log("Found release versions: ", versions);
  return versions;
};

const setUp = () => {
  log("Install dependencies");
  childProcess.execSync("npm i --save replace-in-file");
  childProcess.execSync("npm install", { cwd: `./website` });

  removeFolder("tmp");
  fs.mkdirSync("tmp");
};

const cleanUp = () => {
  log("Delete tmp folder");
  removeFolder("tmp");

  log("Delete npm related files");
  removeFolder("node_modules");
  ["package.json", "package-lock.json"].forEach((file) => {
    if (fs.existsSync(file)) {
      fs.unlinkSync(file);
    }
  });
};

const main = () => {
  setUp();

  cloneRepos();

  log("Versioning");
  projectPaths.map((project) => {
    const projectName = project.name;
    const versions = findReleaseVersions(projectName);
    versions.map((version) => {
      log(`Versioning for ${projectName} version: ${version}`);
      childProcess.execSync(`git checkout -f origin/release/${version}`, {
        cwd: `./tmp/${projectName}`,
      });

      log("Replace elements inside MD files");
      replaceMDElements(projectName, [`./tmp/${projectName}/docs`], project.branch);

      copyAllDocs(project);
      // versioning English docs
      childProcess.execSync(
        `npm run docusaurus docs:version:docs-${projectName} ${version}`,
        { cwd: `./website` }
      );
      // versioning Chinese docs
      if (isFileExisted(`./tmp/${projectName}/docs/zh/latest`) !== false) {
        copyFolder(
          project.latestDocs.zh,
          `./website/i18n/zh/docusaurus-plugin-content-docs-docs-${projectName}/version-${version}`
        );
      }
    });
  });

  log("Copy next version docs");
  projectPaths.map((project) => {
    const projectName = project.name;
    childProcess.execSync(`git checkout -f ${project.branch}`, {
      cwd: `./tmp/${projectName}`,
    });

    log("Replace elements inside MD files");
    replaceMDElements(projectName, [`./tmp/${projectName}/docs`], project.branch);
    copyAllDocs(project);
  });

  cleanUp();
};

main();
