// Updates the JS API spec and docs with the list of deprecations specified
// in spec/deprecations.yaml.

import * as colors from 'colors/safe';
import * as crypto from 'crypto';
import * as fs from 'fs';
import {parse} from 'yaml';

interface YamlData {
  [key: string]: {
    description: string;
    'dart-sass': {
      status: 'active' | 'future' | 'obsolete';
      deprecated?: string;
      obsolete?: string;
    };
  };
}

const yamlFile = 'spec/deprecations.yaml';
const specFile = 'spec/js-api/deprecations.d.ts.md';
const docFile = 'js-api-doc/deprecations.d.ts';

const specRegex =
  /<!-- START AUTOGENERATED LIST -->[\s\S]*?<!-- END AUTOGENERATED LIST -->/m;
const docRegex =
  /\/\/ START AUTOGENERATED LIST[\s\S]*?\/\/ END AUTOGENERATED LIST/m;

(async () => {
  const yamlText = fs.readFileSync(yamlFile, 'utf8');
  const oldSpecText = fs.readFileSync(specFile, 'utf8');
  const oldDocText = fs.readFileSync(docFile, 'utf8');

  if (!specRegex.test(oldSpecText)) {
    console.error(
      `${colors.red(colors.bold('Error:'))} ` +
        `Cannot find AUTOGENERATED LIST block in ${specFile}`
    );
    process.exitCode = 1;
    return;
  }
  if (!docRegex.test(oldDocText)) {
    console.error(
      `${colors.red(colors.bold('Error:'))} ` +
        `Cannot find AUTOGENERATED LIST block in ${docFile}`
    );
    process.exitCode = 1;
    return;
  }

  const deprecations = parse(yamlText) as YamlData;
  let specList = '';
  let docList = '';
  for (const [id, deprecation] of Object.entries(deprecations)) {
    const key = id.includes('-') ? `'${id}'` : id;
    specList += `  ${key}: Deprecation<'${id}'>;\n`;
    const lowercase =
      deprecation.description.substring(0, 1).toLowerCase() +
      deprecation.description.substring(1);
    const dartSass = deprecation['dart-sass'];
    const activeText = !dartSass.deprecated
      ? 'This deprecation is not yet active, but will be soon.'
      : dartSass.deprecated === '0.0.0'
      ? 'This deprecation was active in the first version of Dart Sass.'
      : `This deprecation became active in Dart Sass ${dartSass.deprecated}.`;
    const obsoleteText = dartSass.obsolete
      ? `\nIt became obsolete in Dart Sass ${dartSass.obsolete}.`
      : '';
    docList += `  /**
   * Deprecation for ${lowercase.replace(/\$PLATFORM/g, 'JS')}
   *
   * ${activeText}${obsoleteText}
   */
  ${key}: Deprecation<'${id}'>;\n\n`;
  }
  const checksum = crypto.createHash('sha1').update(yamlText).digest('hex');

  const newSpecText = oldSpecText.replace(
    /<!-- START AUTOGENERATED LIST -->[\s\S]*?<!-- END AUTOGENERATED LIST -->/m,
    `<!-- START AUTOGENERATED LIST -->
<!-- Checksum: ${checksum} -->
\`\`\`ts
export interface Deprecations {
${specList}  'user-authored': Deprecation<'user-authored', 'user'>;
}
\`\`\`
<!-- END AUTOGENERATED LIST -->`
  );

  const newDocText = oldDocText.replace(
    /\/\/ START AUTOGENERATED LIST[\s\S]*?\/\/ END AUTOGENERATED LIST/m,
    `// START AUTOGENERATED LIST
  // Checksum: ${checksum}

${docList}  // END AUTOGENERATED LIST`
  );

  fs.writeFileSync(specFile, newSpecText);
  fs.writeFileSync(docFile, newDocText);
})();
