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

import chalk from 'chalk-template';
import esMain from 'es-main';
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';

import bcdData from '../index.js';
import {
  BrowserName,
  CompatStatement,
  SupportStatement,
  Identifier,
} from '../types/types.js';

import { getRefDate } from './release/utils.js';

interface VersionStatsEntry {
  all: number;
  true: number;
  null: number;
  range: number;
  real: number;
}

type VersionStats = Record<string, VersionStatsEntry>;

const webextensionsBrowsers: BrowserName[] = [
  'chrome',
  'edge',
  'firefox',
  'opera',
  'safari',
  'firefox_android',
  'safari_ios',
];

/**
 * Check whether a support statement is a specified type
 * @param supportData The support statement to check
 * @param type What type of support (true, null, ranged)
 * @returns If the support statement has the type
 */
const checkSupport = (
  supportData: SupportStatement | undefined,
  type: string | boolean | null,
): boolean => {
  if (!supportData) {
    return type === null;
  }
  if (Array.isArray(supportData)) {
    return supportData.some((s) => checkSupport(s, type));
  }
  if (type == '≤') {
    return (
      (typeof supportData.version_added == 'string' &&
        supportData.version_added.startsWith('≤')) ||
      (typeof supportData.version_removed == 'string' &&
        supportData.version_removed.startsWith('≤'))
    );
  }
  return (
    supportData.version_added === type || supportData.version_removed === type
  );
};

/**
 * Iterate through all of the browsers and count the number of true, null, real, and ranged values for each browser
 * @param data The data to process and count stats for
 * @param browsers The browsers to test
 * @param stats The stats object to update
 */
const processData = (
  data: CompatStatement,
  browsers: BrowserName[],
  stats: VersionStats,
): void => {
  if (data.support) {
    browsers.forEach((browser) => {
      stats[browser].all++;
      stats.total.all++;
      if (!data.support[browser]) {
        stats[browser].null++;
        stats.total.null++;
      } else if (checkSupport(data.support[browser], null)) {
        stats[browser].null++;
        stats.total.null++;
      } else if (checkSupport(data.support[browser], true)) {
        stats[browser].true++;
        stats.total.true++;
      } else if (checkSupport(data.support[browser], '≤')) {
        stats[browser].range++;
        stats.total.range++;
      } else {
        stats[browser].real++;
        stats.total.real++;
      }
    });
  }
};

/**
 * Iterate through all of the data and process statistics
 * @param data The compat data to iterate
 * @param browsers The browsers to test
 * @param stats The stats object to update
 */
const iterateData = (
  data: Identifier,
  browsers: BrowserName[],
  stats: VersionStats,
) => {
  for (const key in data) {
    if (key === '__compat') {
      // "as CompatStatement" needed because TypeScript doesn't realize key is in data
      processData(data[key] as CompatStatement, browsers, stats);
    } else {
      iterateData(data[key], browsers, stats);
    }
  }
};

/**
 * Get all of the stats
 * @param folder The folder to show statistics for (or all folders if blank)
 * @param allBrowsers If true, get stats for all browsers, not just main eight
 * @param bcd The BCD data to use. Defaults to the main BCD data.
 * @returns The statistics
 */
const getStats = (
  folder: string,
  allBrowsers: boolean,
  bcd = bcdData,
): VersionStats | null => {
  const browsers: BrowserName[] = allBrowsers
    ? (Object.keys(bcd.browsers) as (keyof typeof bcd.browsers)[])
    : folder === 'webextensions'
      ? webextensionsBrowsers
      : ([
          'chrome',
          'chrome_android',
          'edge',
          'firefox',
          'safari',
          'safari_ios',
          'webview_android',
        ] as BrowserName[]);

  const stats: VersionStats = {
    total: { all: 0, true: 0, null: 0, range: 0, real: 0 },
  };
  browsers.forEach((browser) => {
    stats[browser] = { all: 0, true: 0, null: 0, range: 0, real: 0 };
  });

  if (folder) {
    if (folder === 'webextensions') {
      iterateData(bcd[folder], webextensionsBrowsers, stats);
    } else if (bcd[folder]) {
      iterateData(bcd[folder], browsers, stats);
    } else {
      if (process.env.NODE_ENV !== 'test') {
        console.error(chalk`{red.bold Folder "${folder}/" doesn't exist!}`);
      }
      return null;
    }
  } else {
    for (const data in bcd) {
      if (data === 'webextensions') {
        iterateData(
          bcd[data],
          browsers.filter((b) => webextensionsBrowsers.includes(b)),
          stats,
        );
      } else if (data !== 'browsers') {
        iterateData(bcd[data], browsers, stats);
      }
    }
  }

  return stats;
};

/**
 * Get value as either percentage or number as requested
 * @param stats The stats object to get data from
 * @param type The type of statistic to obtain
 * @param counts Whether to return the integer itself
 * @returns The percentage or count
 */
const getStat = (
  stats: VersionStatsEntry,
  type: keyof VersionStatsEntry,
  counts: boolean,
): string | number =>
  counts ? stats[type] : `${((stats[type] / stats.all) * 100).toFixed(2)}%`;

/**
 * Print statistics of BCD
 * @param stats The stats object to print from
 * @param folder The folder to show statistics for (or all folders if blank)
 * @param counts Whether to display a count vs. a percentage
 */
const printStats = (
  stats: VersionStats | null,
  folder: string,
  counts: boolean,
): void => {
  if (!stats) {
    console.error(`No stats${folder ? ` for folder ${folder}` : ''}!`);
    return;
  }

  const releaseDate = getRefDate('v' + process.env.npm_package_version).slice(
    0,
    'YYYY-MM-DD'.length,
  );

  console.log(
    chalk`{bold Status as of version ${
      process.env.npm_package_version
    } (released on ${releaseDate}) for ${
      folder ? `the \`${folder}/\` directory` : 'web platform features'
    }}: \n`,
  );

  let table = `| browser | real values | ranged values | \`true\` values | \`null\` values |
| --- | --- | --- | --- | --- |
`;

  Object.keys(stats).forEach((entry) => {
    table += `| ${entry.replace('_', ' ')} | `;
    table += `${getStat(stats[entry], 'real', counts)} | `;
    table += `${getStat(stats[entry], 'range', counts)} | `;
    table += `${getStat(stats[entry], 'true', counts)} | `;
    table += `${getStat(stats[entry], 'null', counts)} |
`;
  });

  console.log(table);
};

if (esMain(import.meta)) {
  const { argv }: { argv } = yargs(hideBin(process.argv)).command(
    '$0 [folder]',
    'Print a markdown-formatted table displaying the statistics of real, ranged, true, and null values for each browser',
    (yargs) => {
      yargs
        .positional('folder', {
          describe: 'Limit the statistics to a specific folder',
          type: 'string',
          default: '',
        })
        .option('all', {
          alias: 'a',
          describe: 'Show statistics for all browsers within BCD',
          type: 'boolean',
          nargs: 0,
        })
        .option('counts', {
          alias: 'c',
          describe: 'Show feature count rather than percentages',
          type: 'boolean',
          nargs: 0,
        });
    },
  );

  printStats(getStats(argv.folder, argv.all), argv.folder, argv.counts);
}

export default getStats;
