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

import { styleText } from 'node:util';

import { createStatementGroupKey } from '../utils.js';

/** @import {Linter, LinterData} from '../types.js' */
/** @import {Logger} from '../utils.js' */
/** @import {BrowserName, CompatStatement, SupportStatement} from '../../types/types.js' */

/**
 * Process data and check to make sure there aren't multiple support statements without
 * `partial_implementation` or `prefix`/`alternative_name`
 * @param {SupportStatement} data The data to test
 * @param {BrowserName} browser The name of the browser
 * @param {Logger} logger The logger to output errors to
 * @returns {void}
 */
const processData = (data, browser, logger) => {
  if (!Array.isArray(data)) {
    // If there's only one statement, skip since this is a linter for multiple statements
    return;
  }

  /** @type {string[]} */
  const statements = [];

  for (const d of data) {
    if (d.partial_implementation || d.version_removed || d.flags) {
      // If statement is of partial_implementation, has a version_removed, or is behind a flag, ignore
      continue;
    }

    const statementKey = createStatementGroupKey(d);

    if (statements.includes(statementKey)) {
      logger.error(
        `${styleText('bold', browser)} has multiple statements for ${styleText('bold', statementKey)} exist without partial implementation! Please ${styleText('bold', 'merge')} these statements and ${styleText('bold', 'combine')} their notes, or set ${styleText('bold', 'partial_implementation')} to ${styleText('bold', 'true')} on applicable statements.`,
      );
    }
    statements.push(statementKey);
  }
};

/** @type {Linter} */
export default {
  name: 'Multiple Statements',
  description:
    'Ensure there are not multiple statements without partial implementation or prefixes/alt. names',
  scope: 'feature',
  /**
   * Test the data
   * @param {Logger} logger The logger to output errors to
   * @param {LinterData} root The data to test
   */
  check: (logger, { data }) => {
    for (const [browser, support] of Object.entries(
      /** @type {CompatStatement} */ (data).support,
    )) {
      processData(
        /** @type {SupportStatement} */ (support),
        /** @type {BrowserName} */ (browser),
        logger,
      );
    }
  },
};
