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

/** @import {CompatData, BrowserName, Identifier, ReleaseStatement, SimpleSupportStatement} from '../../types/types.js' */

import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

import esMain from 'es-main';

import { walk } from '../../utils/index.js';
import { dataFoldersMinusBrowsers } from '../lib/data-folders.js';
import bcd from '../../index.js';
const { browsers } = bcd;

const dirname = fileURLToPath(new URL('.', import.meta.url));

/**
 * Fix the experimental status throughout compatibility data
 * @param {CompatData | Identifier} bcd Parsed BCD object to be updated in place.
 * @returns {void}
 */
export const fixExperimental = (bcd) => {
  for (const { compat } of walk(undefined, bcd)) {
    if (!compat.status?.experimental) {
      continue;
    }

    // This entry is marked as experimental. Check which browsers support it.

    /** @type {Set<BrowserName>} */
    const browserSupport = new Set();

    for (const [browser, support] of Object.entries(compat.support)) {
      if (!support) {
        continue;
      }

      // Consider only the first part of an array statement.
      /** @type {SimpleSupportStatement} */
      const statement = Array.isArray(support) ? support[0] : support;

      // Ignore anything behind flag, prefix or alternative name
      if (statement.flags || statement.prefix || statement.alternative_name) {
        continue;
      }
      if (statement.version_added && !statement.version_removed) {
        browserSupport.add(/** @type {BrowserName} */ (browser));
      }
    }

    // Now check which of Blink, Gecko and WebKit support it.

    const engineSupport = new Set();

    for (const browser of browserSupport) {
      const currentRelease = Object.values(browsers[browser].releases).find(
        (/** @type {ReleaseStatement} */ r) => r.status === 'current',
      );
      if (!currentRelease) {
        continue;
      }
      const engine = currentRelease.engine;
      engineSupport.add(engine);
    }

    let engineCount = 0;
    for (const engine of ['Blink', 'Gecko', 'WebKit']) {
      if (engineSupport.has(engine)) {
        engineCount++;
      }
    }

    if (engineCount > 1) {
      compat.status.experimental = false;
    }
  }
};

/**
 * Fix the experimental status throughout a file
 * @param {string} filename Filename of BCD to be updated in place.
 * @returns {void}
 */
const fixExperimentalFile = (filename) => {
  const actual = fs.readFileSync(filename, 'utf-8').trim();
  const bcd = JSON.parse(actual);
  fixExperimental(bcd);
  const expected = JSON.stringify(bcd, null, 2);

  if (actual !== expected) {
    fs.writeFileSync(filename, expected + '\n', 'utf-8');
  }
};

/**
 * Load files and fix experimental status
 * @param {...string} files The files to fix
 * @returns {void}
 */
const load = (...files) => {
  for (let file of files) {
    if (file.indexOf(dirname) !== 0) {
      file = path.resolve(dirname, '..', '..', file);
    }

    if (!fs.existsSync(file)) {
      continue; // Ignore non-existent files
    }

    if (fs.statSync(file).isFile()) {
      if (path.extname(file) === '.json') {
        fixExperimentalFile(file);
      }

      continue;
    }

    const subFiles = fs
      .readdirSync(file)
      .map((subfile) => path.join(file, subfile));

    load(...subFiles);
  }
};

if (esMain(import.meta)) {
  if (process.argv[2]) {
    load(process.argv[2]);
  } else {
    load(...dataFoldersMinusBrowsers);
  }
}
