/* eslint-disable max-len */
const childProcess = require('child_process');
const fs = require('fs/promises');
const path = require('path');
const process = require('process');
const os = require('os');
const Listr = require('listr');
const simpleGit = require('simple-git');
const semver = require('semver');
const replace = require('replace-in-file');

const common = require('./common.js');
const { versions, versionMap } = require('../config/apisix-versions.js');

const { projects, languages, projectPaths } = common;
const tempPath = './temp';
const websitePath = '../doc';
const gitMap = {};
const projectReleases = {};

const tasks = new Listr([
  {
    title: 'Start documents sync',
    task: async () => {
      if (!(await isDirExisted(tempPath))) {
        await fs.mkdir(tempPath);
      }
    },
  },
  {
    title: 'Clone git repositories',
    task: () => {
      const gitTasks = projects.map((project) => ({
        title: `Clone ${project.name} repository`,
        task: async () => {
          const { name } = project;
          const dir = `${tempPath}/${name}/`;
          const exist = await isDirExisted(dir);
          if (exist) {
            gitMap[name] = simpleGit(dir);
            // Use more robust fetch for existing repositories
            await gitMap[name]
              .cwd(dir)
              .fetch(['--prune', '--recurse-submodules=no']);
          } else {
            gitMap[name] = simpleGit();
            // Use more robust clone without filter in CI environment
            const isCI = process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true';
            const cloneOptions = isCI
              ? {
                '--sparse': true,
                '--recurse-submodules': 'no',
              }
              : {
                '--filter': 'blob:none',
                '--sparse': true,
                '--recurse-submodules': 'no',
              };

            await gitMap[name]
              .clone(`https://github.com/apache/${name}.git`, dir, cloneOptions)
              .cwd(dir)
              .raw(['sparse-checkout', 'set', 'docs']);

            if (name === 'apisix') {
              await gitMap[name]
                .cwd(dir)
                .raw(['sparse-checkout', 'add', 'apisix/core', 'autodocs']);
            }
          }
        },
      }));
      return new Listr(gitTasks, { concurrent: projects.length });
    },
  },
  {
    title: 'Find project release',
    task: () => {
      const findReleaseTasks = projects
        .filter((p) => p.name !== 'apisix')
        .map((project) => ({
          title: `Find ${project.name} releases`,
          task: async () => {
            const ret = await gitMap[project.name].cwd(`${tempPath}/${project.name}/`).branch();
            if (ret.all) {
              const isIngressController = project.name === 'apisix-ingress-controller';
              projectReleases[project.name] = ret.all
                .filter((release) => (isIngressController
                  ? release.includes('remotes/origin/v')
                  && semver.gt(release.replace('remotes/origin/v', ''), '0.3.0')
                  : release.includes('remotes/origin/release/')))
                .map((release) => (isIngressController
                  ? release.replace('remotes/origin/v', '')
                  : release.replace('remotes/origin/release/', '')))
                .sort((a, b) => semver.compare(semver.coerce(a).version, semver.coerce(b).version));
            }
          },
        }));
      return new Listr(findReleaseTasks, { concurrent: projects.length });
    },
  },
  {
    title: 'Extract documents',
    task: () => {
      // add apisix versions to release
      projectReleases.apisix = versions;

      const writeVersion2File = async (target, versions) => {
        if (versions.length === 0) return Promise.resolve();

        if (await isFileExisted(target)) await fs.rm(target);
        return fs.writeFile(
          target,
          JSON.stringify(versions.map((v) => versionMap[v] || v).reverse(), null, 2),
        );
      };

      const extractTasks = projectPaths.map((project) => ({
        title: `Extract ${project.name}`,
        task: () => new Listr([
          {
            title: `Create target dir`,
            task: async () => {
              const projectName = project.name;
              const docs = `${websitePath}/docs-${projectName}_versioned_docs`;
              const sidebar = `${websitePath}/docs-${projectName}_versioned_sidebars`;
              const versions = `${websitePath}/docs-${projectName}_versions.json`;
              const i18nDocs = `${websitePath}/i18n/zh/docusaurus-plugin-content-docs-docs-${projectName}`;

              await Promise.allSettled([
                removeFolder(docs),
                removeFolder(sidebar),
                removeFolder(i18nDocs),
                writeVersion2File(versions, projectReleases[projectName]),
              ]);
            },
          },
          {
            title: `Extract ${project.name} release versions documents`,
            task: () => {
              const steps = projectReleases[project.name].map((version) => ({
                title: `Extract ${project.name} ${version} documents`,
                task: () => extractDocsVersionTasks(project, version),
              }));
              return new Listr(steps);
            },
          },
          {
            title: `Extract ${project.name} next version documents`,
            skip: () => project.name === 'apisix-dashboard',
            task: () => extractDocsNextVersionTasks(project, project.branch),
          },
        ]),
      }));
      return new Listr(extractTasks, { concurrent: projects.length });
    },
  },
]);

tasks
  .run()
  .then(() => {
    console.log('[Finish] Documents synchronize success');
  })
  .catch((err) => {
    console.error(err);
    process.exit(1);
  });

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function log(text) {
  // console.log(text);
}

async function replaceMDElements(project, path, branch = 'master') {
  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}`;
      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-', '');
      const newUrl = match.replace(
        /\]\(.*\)/g,
        `](https://apisix.apache.org${lang === 'en' ? '' : `/${lang}`
        }/docs/${projectNameWithoutPrefix}/${urlPath})`,
      );
      log(`${project}: ${match} 👉 ${newUrl}`);
      return newUrl;
    },
  };

  await replace(imageOptions);
  await replace(markdownOptions);
}

async function isFileExisted(p) {
  return fs
    .stat(p)
    .then((v) => v.isFile())
    .catch(() => false);
}

async function isDirExisted(p) {
  return fs
    .stat(p)
    .then((v) => v.isDirectory())
    .catch(() => false);
}

async function removeFolder(tarDir) {
  if (await isDirExisted()) return;
  await fs.rm(tarDir, { recursive: true, force: true });
}

async function copyFolder(srcDir, tarDir) {
  const [files] = await Promise.all([fs.readdir(srcDir), fs.mkdir(tarDir, { recursive: true })]);

  return Promise.allSettled(
    files.map(async (file) => {
      const srcPath = path.join(srcDir, file);
      const tarPath = path.join(tarDir, file);

      if (await isDirExisted(srcPath)) {
        return copyFolder(srcPath, tarPath);
      }
      if (await isFileExisted(srcPath)) {
        return fs.copyFile(srcPath, tarPath);
      }
      return Promise.resolve();
    }),
  );
}

async function copyDocs(source, target) {
  if (!(await isDirExisted(source))) {
    log(`cannot find ${source}, skip.`);
    return Promise.reject(new Error(`${source} no exist`));
  }

  return copyFolder(source, target);
}

function normalizeSidebar(sidebarList, version) {
  const arr = sidebarList.map((block) => ({
    ...block,
    ...(block?.id ? { id: `version-${version}/${block.id}` } : {}),
    ...(block?.items?.length > 0
      ? {
        collapsible: true,
        collapsed: true,
        items: block.items.map((v) => {
          if (typeof v === 'string') {
            return {
              type: 'doc',
              id: `version-${version}/${v}`,
            };
          }
          return normalizeSidebar([v], version)[`version-${version}/docs`][0];
        }),
      }
      : {}),
  }));

  return {
    [`version-${version}/docs`]: arr,
  };
}

async function handleConfig2Sidebar(source, target, version, versionedTarget) {
  log(`load ${source} latest docs config.json`);
  const config = JSON.parse(await fs.readFile(`${source}/config.json`));

  const sidebar = JSON.stringify({ docs: config.sidebar || [] }, null, 2);

  const writeVersionedSidebar = async () => {
    if (typeof version === 'undefined') return Promise.resolve();

    const versionedSidebar = JSON.stringify(normalizeSidebar(config.sidebar, version), null, 2);
    await fs.mkdir(versionedTarget, { recursive: true });
    return fs.writeFile(`${versionedTarget}/version-${version}-sidebars.json`, versionedSidebar);
  };

  await Promise.allSettled([
    fs.unlink(`${source}/config.json`),
    fs.writeFile(`${target}/sidebars.json`, sidebar),
    writeVersionedSidebar(),
  ]);
}

/**
 * Generate APISIX API Docs
 * @return {Listr<Listr.ListrContext>}
 * @param project
 * @param version
 */
function generateAPIDocs(project) {
  const dir = `./${tempPath}/${project.name}`;
  return new Listr([
    {
      title: 'Generate markdown files',
      task: () => {
        childProcess.spawnSync(`autodocs/generate.sh`, ['build'], {
          cwd: dir,
        });
      },
    },
    {
      title: 'Copy API docs',
      task: async () => {
        if (
          await copyDocs(`${dir}/autodocs/output`, `${dir}/pdk-docs`)
            .then(() => true)
            .catch(() => false)
        ) {
          await fs.rm(`${dir}/autodocs/output`, { recursive: true });
        }
      },
    },
  ]);
}

function extractDocsVersionTasks(project, version) {
  const projectPath = `${tempPath}/${project.name}`;
  const isIngressController = project.name === 'apisix-ingress-controller';
  return new Listr([
    {
      title: `Checkout ${project.name} version: ${version}`,
      task: () => gitMap[project.name]
        .cwd(projectPath)
        .checkout(
          isIngressController
            ? `remotes/origin/v${version}`
            : `remotes/origin/release/${version}`,
          ['-f'],
        ),
    },
    {
      title: 'Generate API docs for APISIX',
      enabled: () => project.name === 'apisix'
        && os.platform() === 'linux'
        && isFileExisted(`./${tempPath}/${project.name}/autodocs`),
      task: () => generateAPIDocs(project),
    },
    {
      title: `Copy to target path`,
      task: async () => {
        const branchName = isIngressController ? `v${version}` : `release/${version}`;
        const projectName = project.name;

        const docsPath = `${projectPath}/docs`;
        const enSrcDocs = `${docsPath}/en/latest`;
        const zhSrcDocs = `${docsPath}/zh/latest`;
        const displayVersionName = (projectName === 'apisix' && versionMap?.[version]) || version;
        const enTargetDocs = `${websitePath}/docs-${projectName}_versioned_docs/version-${displayVersionName}`;
        const zhTargetDocs = `${websitePath}/i18n/zh/docusaurus-plugin-content-docs-docs-${projectName}/version-${displayVersionName}`;

        await Promise.allSettled([
          copyDocs(enSrcDocs, enTargetDocs)
            .then(() => replaceMDElements(projectName, [enTargetDocs], branchName))
            .then(() => handleConfig2Sidebar(
              enTargetDocs,
              enTargetDocs,
              displayVersionName,
              `${websitePath}/docs-${project.name}_versioned_sidebars`,
            )),
          copyDocs(zhSrcDocs, zhTargetDocs).then(() => replaceMDElements(projectName, [zhTargetDocs], branchName)),
        ]).catch(() => {
          /* ignore */
        });
      },
    },
  ]);
}

function extractDocsNextVersionTasks(project, version) {
  const projectPath = `${tempPath}/${project.name}`;
  return new Listr([
    {
      title: `Checkout ${project.name} version: ${version}`,
      task: () => gitMap[project.name].cwd(projectPath).checkout(`remotes/origin/${version}`, ['-f']),
    },
    {
      title: 'Generate API docs for APISIX',
      enabled: () => project.name === 'apisix'
        && os.platform() === 'linux'
        && isFileExisted(`./${projectPath}/autodocs`),
      task: () => generateAPIDocs(project),
    },
    {
      title: `Copy to target path`,
      task: async () => {
        const branchName = project.branch;
        const projectName = project.name;

        const docsPath = `${projectPath}/docs`;
        const enSrcDocs = `${docsPath}/en/latest`;
        const zhSrcDocs = `${docsPath}/zh/latest`;
        const enTargetDocs = `${websitePath}/docs/${projectName}`;
        const zhTargetDocs = `${websitePath}/i18n/zh/docusaurus-plugin-content-docs-docs-${projectName}/current`;

        await Promise.all([
          copyDocs(enSrcDocs, enTargetDocs)
            .then(() => replaceMDElements(projectName, [enTargetDocs], branchName))
            .then(() => handleConfig2Sidebar(enTargetDocs, enTargetDocs)),
          copyDocs(zhSrcDocs, zhTargetDocs).then(() => replaceMDElements(projectName, [zhTargetDocs], branchName)),
        ]).catch(() => {
          /* ignore */
        });
      },
    },
  ]);
}
