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

/**
 * @typedef {object} Stats
 * @property {number} commits
 * @property {number} changed
 * @property {number} insertions
 * @property {number} deletions
 * @property {number} releaseContributors
 * @property {number} totalContributors
 * @property {number} features
 * @property {number} stars
 * @property {string} start
 * @property {string} end
 */

/**
 * @typedef {Pick<Stats, 'commits' | 'changed' | 'insertions' | 'deletions'>} ChangeStats
 */

import { styleText } from 'node:util';

import { spawn, walk } from '../../utils/index.js';
import pluralize from '../lib/pluralize.js';

import { queryPRs, githubAPI } from './utils.js';

/**
 * Get stargazers for the repository
 * @returns {Promise<number>} The number of stargazer
 */
const stargazers = async () => {
  const json = githubAPI('');
  return json.stargazers_count;
};

/**
 * Get the number of contributors that have committed to the repository
 * @returns {number} The number of contributors that have contributed to the repository
 */
const contributors = () => {
  const data = spawn('gh', [
    'api',
    '/repos/mdn/browser-compat-data/contributors?anon=1',
    '--paginate',
  ]);
  return JSON.parse('[' + data.replace(/\]\[/g, '],[') + ']').flat(1).length;
};

/**
 * Get all of the stats for the release
 * @param {string} start The last version number
 * @returns {ChangeStats} The statistics
 */
const stats = (start) => {
  // Get just the diff stats summary
  const diff = spawn('git', ['diff', '--shortstat', `${start}...origin/main`]);
  if (diff === '') {
    console.error(
      styleText('red', 'No changes for which to generate statistics.'),
    );
    process.exit(1);
  }

  // Extract the numbers from a line like this:
  // 50 files changed, 1988 insertions(+), 2056 deletions(-)
  const match = diff.match(
    /(?<changed>\d+) files? changed(?:, (?<insertions>\d+) insertions?(\(\+\)))?(?:, (?<deletions>\d+) deletions?\(-\))?/,
  );
  if (!match) {
    console.error(
      styleText('red', 'No changes for which to generate statistics.'),
    );
    process.exit(1);
  }

  const { changed, insertions, deletions } = /** @type {*} */ (match.groups);

  // Get the number of commits
  const commits = spawn('git', [
    'rev-list',
    '--count',
    `${start}...origin/main`,
  ]);

  return {
    commits: Number(commits),
    changed: Number(changed) || 0,
    insertions: Number(insertions) || 0,
    deletions: Number(deletions) || 0,
  };
};

/**
 * Get the number of contributors that have committed to this release
 * @param {string} fromDate The date of the last release
 * @returns {Set<string>} The authors of the commits
 */
const getReleaseContributors = (fromDate) => {
  const prs = queryPRs({
    json: 'author',
    search: `merged:>=${fromDate}`,
  });
  return new Set(prs.map((pr) => pr.author.login));
};

/**
 * Count the number of features in BCD
 * @returns {number} The number of features
 */
const countFeatures = () => [...walk()].length;

/**
 * Format the stats as Markdown
 * @param {Stats} details The stats to format
 * @returns {string} The formatted stats
 */
export const formatStats = (details) =>
  [
    '### Statistics',
    '',
    `- ${pluralize('contributor', details.releaseContributors)} ${
      details.releaseContributors > 1 ? 'have' : 'has'
    } changed ${pluralize('file', details.changed)} with ${pluralize(
      'addition',
      details.insertions,
    )} and ${pluralize('deletion', details.deletions)} in ${pluralize(
      'commit',
      details.commits,
    )} ([\`${details.start}...${
      details.end
    }\`](https://github.com/mdn/browser-compat-data/compare/${
      details.start
    }...${details.end}))`,
    `- ${pluralize('total feature', details.features)}`,
    `- ${pluralize('total contributor', details.totalContributors)}`,
    `- ${pluralize('total stargazer', details.stars)}`,
    '',
  ].join('\n');

/**
 * Get the statistics for the release
 * @param {string} start The last release number
 * @param {string} end This release number
 * @param {string} startDate The date of the last release
 * @returns {Promise<Stats>} The release statistics
 */
export const getStats = async (start, end, startDate) => ({
  start,
  end,
  ...stats(start),
  releaseContributors: getReleaseContributors(startDate).size,
  totalContributors: contributors(),
  stars: await stargazers(),
  features: countFeatures(),
});
