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

import chalk from 'chalk-template';
import xml2js from 'xml2js';

const USER_AGENT =
  'MDN-Browser-Release-Update-Bot/1.0 (+https://developer.mozilla.org/)';

export interface RSSItem {
  title: string;
  pubDate: string;
  description: string;
  link: string;
}

/**
 * newBrowserEntry - Add a new browser entry in the JSON list
 * @param json json file to update
 * @param browser the entry name where to add it in the bcd file
 * @param version new version to add
 * @param status new status
 * @param engine name of the engine
 * @param releaseDate new release date
 * @param releaseNotesURL url of the release notes
 * @param engineVersion the version of the engine
 * @returns Text describing what has been added
 */
export const newBrowserEntry = (
  json,
  browser,
  version,
  status,
  engine,
  releaseDate,
  releaseNotesURL,
  engineVersion,
) => {
  const release = (json.browsers[browser].releases[version] = {});
  if (releaseDate) {
    release['release_date'] = releaseDate;
  }
  if (releaseNotesURL) {
    release['release_notes'] = releaseNotesURL;
  }
  release['status'] = status;
  release['engine'] = engine;
  if (engineVersion) {
    release['engine_version'] = engineVersion;
  }
  return chalk`{yellow \n- New release detected for {bold ${browser}}: Version {bold ${version}} as a {bold ${status}} release.}`;
};

/**
 * updateBrowserEntry - Update browser entry in the JSON list
 * @param json json file to update
 * @param browser the entry name where to add it in the bcd file
 * @param version new version to add
 * @param releaseDate new release date
 * @param status new status
 * @param releaseNotesURL url of the release notes
 * @param engineVersion the version of the engine
 * @returns Text describing what has been updated
 */
export const updateBrowserEntry = (
  json,
  browser,
  version,
  releaseDate,
  status,
  releaseNotesURL,
  engineVersion,
) => {
  const entry = json.browsers[browser].releases[version];
  let result = '';
  if (entry['status'] !== status) {
    result += chalk`{cyan \n- New status for {bold ${browser} ${version}}: {bold ${status}}, previously ${entry['status']}.}`;
    entry['status'] = status;
  }
  if (releaseDate && entry['release_date'] !== releaseDate) {
    result += chalk`{cyan \n- New release date for {bold ${browser} ${version}}: {bold ${releaseDate}}, previously ${entry['release_date']}.}`;
    entry['release_date'] = releaseDate;
  }
  if (releaseNotesURL && entry['release_notes'] !== releaseNotesURL) {
    result += chalk`{cyan \n- New release notes for {bold ${browser} ${version}}: {bold ${releaseNotesURL}}, previously ${entry['release_notes']}.}`;
    entry['release_notes'] = releaseNotesURL;
  }

  if (engineVersion && entry['engine_version'] != engineVersion) {
    result += chalk`{cyan \n- New engine version for {bold ${browser} ${version}}: {bold ${engineVersion}}, previously ${entry['engine_version']}.}`;
    entry['engine_version'] = engineVersion;
  }

  return result;
};

/**
 * Creates or updates a browser entry, depending on whether it already exists.
 * @param json json file to update
 * @param browser the entry name where to add it in the bcd file
 * @param version the version to add
 * @param status the status
 * @param engine the name of the negine
 * @param engineVersion the version of the engine
 * @param releaseDate the release date
 * @param releaseNotesURL url of the release notes
 * @returns Text describing what has been updated
 */
export const createOrUpdateBrowserEntry = (
  json,
  browser,
  version,
  status: 'retired' | 'current' | 'beta' | 'nightly',
  engine: string | undefined,
  engineVersion: string | undefined,
  releaseDate: string | undefined = undefined,
  releaseNotesURL: string | undefined = undefined,
) => {
  if (json.browsers[browser].releases[version]) {
    return updateBrowserEntry(
      json,
      browser,
      version,
      releaseDate,
      status,
      releaseNotesURL,
      engineVersion,
    );
  }

  return newBrowserEntry(
    json,
    browser,
    version,
    status,
    engine,
    releaseDate,
    releaseNotesURL,
    engineVersion,
  );
};

/**
 * Fetches an RSS feed, using a typical RSS user agent.
 * @param url The URL of the RSS feed.
 * @returns Promise
 */
const fetchRSS = async (url: string) => {
  const response = await fetch(url, {
    headers: {
      'User-Agent': USER_AGENT,
    },
  });

  if (!response.ok) {
    throw new Error(`HTTP ${response.status}`);
  }

  return await response.text();
};

/**
 * Parses an RSS feed into a JSON object.
 * @param rssText The content of the RSS feed.
 * @returns the RSS items.
 */
const parseRSS = async (rssText: string): Promise<RSSItem[]> => {
  const parser = new xml2js.Parser({ explicitArray: false });

  const result = await parser.parseStringPromise(rssText);

  return result.rss.channel.item;
};

/**
 * Fetches and parses an RSS feed.
 * @param url The URL of the RSS feed.
 * @returns the RSS items.
 */
export const getRSSItems = async (url): Promise<RSSItem[]> => {
  const rssText = await fetchRSS(url);
  const items = await parseRSS(rssText);

  return Array.isArray(items) ? items : [items];
};
