/* This file is a part of @mdn/browser-compat-data
 * See LICENSE file for more information. */

/** @import {Identifier} from '../types/types.js' */

import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
import { join, relative, resolve, sep } from 'node:path';

import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';

const argv = yargs(hideBin(process.argv))
  .command('$0 [files..]', 'Split BCD JSON files')
  .positional('files', {
    array: true,
    describe: 'One or more JSON files to split',
    type: 'string',
    default: [],
  })
  .help()
  .parseSync();

/**
 * Extracts the base key path (as array of strings) from a JSON file path.
 *
 * For example, `api/AbortController.json` becomes `['api', 'AbortController']`.
 * @param {string} filePath - The path to the BCD JSON file
 * @returns {string[]} Array of path components without the `.json` extension
 */
const getBaseKeyFromPath = (filePath) => {
  const relativePath = filePath.replace(/\.json$/, '').split(sep);
  return relativePath;
};

/**
 * Creates the JSON for the subfeature.
 * @param {string[]} baseKeys - The parent keys in which to nest the data.
 * @param {string} key - The key of the subfeature.
 * @param {Identifier} value - The value of the subfeature.
 * @returns {object} JSON for the subfeature data nested in parent structure.
 */
const createSubfeatureJSON = (baseKeys, key, value) => {
  const data = {};
  let current = data;

  for (const baseKey of baseKeys) {
    current[baseKey] = {};
    current = current[baseKey];
  }

  current[key] = value;

  return data;
};

/**
 * Checks if data contains compat data.
 * @param {any} data - The data to check for `__compat` entries.
 * @returns {boolean} TRUE, if the data contains any compat data.
 */
const hasCompatData = (data) =>
  '__compat' in data ||
  (typeof data === 'object' && Object.values(data).some(hasCompatData));

/**
 * Writes a JSON file.
 * @param {string} path - The path to the file.
 * @param {Identifier} data - The data to write as JSON.
 * @returns {Promise<void>} Promise.
 */
const writeJSONFile = async (path, data) =>
  writeFile(path, JSON.stringify(data, null, 2) + '\n');

/**
 * Splits a BCD-style JSON file into separate files for each subfeature.
 * Each file will include only the `__compat` data of a given property.
 * Extracted entries are also removed from the original file.
 * @param {string} file - The absolute or relative path to the source JSON file
 */
const splitFile = async (file) => {
  const fullPath = resolve(file);
  const raw = await readFile(fullPath, 'utf-8');
  const data = /** @type {Identifier} */ (JSON.parse(raw));

  const baseKeys = getBaseKeyFromPath(file);
  let current = data;

  for (const key of baseKeys) {
    if (!(key in current)) {
      console.error(`❌ Error: Key "${key}" not found in structure.`);
      return;
    }
    current = current[key];
  }

  const dirPath = fullPath.replace(/\.json$/, '');

  // Write file for each subfeature, then remove subfeature from parent file.
  for (const [key, value] of Object.entries(current)) {
    if (key === '__compat') {
      continue;
    }
    if (typeof value === 'object' && value !== null && '__compat' in value) {
      const data = createSubfeatureJSON(baseKeys, key, value);

      await mkdir(dirPath, { recursive: true });
      const outFile = join(dirPath, `${key}.json`);
      await writeJSONFile(outFile, data);
      console.log(`✔ Created: ${relative(process.cwd(), outFile)}`);

      Reflect.deleteProperty(current, key);
    }
  }

  // Check if current file still has any data.
  if (hasCompatData(data)) {
    await writeJSONFile(fullPath, data);
    console.log(`✔ Updated: ${file}`);
  } else {
    await rm(fullPath);
    console.log(`✔ Deleted: ${file}`);
  }
};

await Promise.all(argv.files.map(splitFile));
