// Copyright 2019 The Chromium Authors. All rights reserved.
// Copyright (C) Microsoft Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * This script is part of the presubmit check that parses DevTools frontend .js and
 * module.json files, collects localizable strings, checks if frontend strings are
 * in .grd/.grdp files and reports error if present.
 *
 * If argument '--autofix' is present, add the new resources to and remove unused
 * messages from GRDP files.
 */

const fs = require('fs');
const {promisify} = require('util');
const writeFileAsync = promisify(fs.writeFile);
const appendFileAsync = promisify(fs.appendFile);
const checkLocalizedStrings = require('./utils/check_localized_strings');
const localizationUtils = require('./utils/localization_utils');

const grdpFileStart = '<?xml version="1.0" encoding="utf-8"?>\n<grit-part>\n';
const grdpFileEnd = '</grit-part>';

async function main() {
  try {
    const shouldAutoFix = process.argv.includes('--autofix');
    const error = await checkLocalizedStrings.validateGrdAndGrdpFiles(shouldAutoFix);
    if (error !== '' && !shouldAutoFix)
      throw new Error(error);

    await checkLocalizedStrings.parseLocalizableResourceMaps();
    if (shouldAutoFix)
      await autofix(error);
    else
      getErrors();
  } catch (e) {
    console.log(e.stack);
    process.exit(1);
  }
}

main();

function getErrors(existingError) {
  const toAddError = checkLocalizedStrings.getAndReportResourcesToAdd();
  const toModifyError = checkLocalizedStrings.getAndReportIDSKeysToModify();
  const toRemoveError = checkLocalizedStrings.getAndReportResourcesToRemove();
  let error =
      `${existingError ? `${existingError}\n` : ''}${toAddError || ''}${toModifyError || ''}${toRemoveError || ''}`;

  if (error === '') {
    console.log('DevTools localizable resources checker passed.');
    return;
  }

  error += '\nThe errors are potentially fixable with the `--autofix` option.';

  throw new Error(error);
}

async function autofix(existingError) {
  const keysToAddToGRD = checkLocalizedStrings.getMessagesToAdd();
  const keysToRemoveFromGRD = checkLocalizedStrings.getMessagesToRemove();
  const resourceAdded = await addResourcesToGRDP(keysToAddToGRD, keysToRemoveFromGRD);
  const resourceModified = await modifyResourcesInGRDP();
  const resourceRemoved = await removeResourcesFromGRDP(keysToRemoveFromGRD);
  const shouldAddExampleTag = checkShouldAddExampleTag(keysToAddToGRD);

  if (!resourceAdded && !resourceRemoved && !resourceModified && existingError === '') {
    console.log('DevTools localizable resources checker passed.');
    return;
  }

  let message =
      'Found changes to localizable DevTools resources.\nDevTools localizable resources checker has updated the appropriate grd/grdp file(s).';
  if (existingError !== '') {
    message +=
        `\nGrd/Grdp files have been updated. Please verify the updated grdp files and/or the <part> file references in ${
            localizationUtils.getRelativeFilePathFromSrc(localizationUtils.GRD_PATH)} are correct.`;
  }
  if (resourceAdded) {
    message += '\nManually write a description for any new <message> entries.';
    if (shouldAddExampleTag) {
      message += ' Add example tag(s) <ex> for messages that contain placeholder(s)';
    }
    message += '\nFor more details, see devtools/docs/langpacks/grdp_files.md';
  }
  if (resourceRemoved && duplicateRemoved(keysToRemoveFromGRD))
    message += '\nDuplicate <message> entries are removed. Please verify the retained descriptions are correct.';
  message += '\n'
  message += '\nUse git status to see what has changed.';
  throw new Error(message);
}

function checkShouldAddExampleTag(keys) {
  if (keys.size === 0) {
    return false;
  }
  const stringObjs = [...keys.values()];
  const stringsWithArgument = stringObjs.filter(stringObj => !!stringObj.arguments);
  return stringsWithArgument.length > 0;
}

function duplicateRemoved(keysToRemoveFromGRD) {
  for (const [_, messages] of keysToRemoveFromGRD) {
    if (messages.length > 1)
      return true;
  }
  return false;
}

// Return true if any resources are added
async function addResourcesToGRDP(keysToAddToGRD, keysToRemoveFromGRD) {
  function mapGRDPFilePathToStrings(keysToAddToGRD, keysToRemoveFromGRD) {
    const grdpFilePathToStrings = new Map();
    // Get the grdp files that need to be modified
    for (const [key, stringObj] of keysToAddToGRD) {
      if (!grdpFilePathToStrings.has(stringObj.grdpPath))
        grdpFilePathToStrings.set(stringObj.grdpPath, []);

      // Add the IDS key to stringObj so we have access to it later
      stringObj.ids = key;
      // If the same key is to be removed, this is likely a string copy
      // to another folder. Keep the description.
      if (keysToRemoveFromGRD.has(key))
        stringObj.description = checkLocalizedStrings.getLongestDescription(keysToRemoveFromGRD.get(key));
      grdpFilePathToStrings.get(stringObj.grdpPath).push(stringObj);
    }
    return grdpFilePathToStrings;
  }

  if (keysToAddToGRD.size === 0)
    return false;

  // Map grdp file path to strings to be added to that file so that we only need to
  // modify every grdp file once
  const grdpFilePathToStrings = mapGRDPFilePathToStrings(keysToAddToGRD, keysToRemoveFromGRD);
  const promises = [];

  const grdpFilePathsToAdd = [];
  for (let [grdpFilePath, stringsToAdd] of grdpFilePathToStrings) {
    // The grdp file doesn't exist, so create one.
    if (!fs.existsSync(grdpFilePath)) {
      let grdpMessagesToAdd = '';
      for (const stringObj of stringsToAdd)
        grdpMessagesToAdd += localizationUtils.createGrdpMessage(stringObj.ids, stringObj);

      // Create a new grdp file and reference it in the parent grd file
      promises.push(appendFileAsync(grdpFilePath, `${grdpFileStart}${grdpMessagesToAdd}${grdpFileEnd}`));
      grdpFilePathsToAdd.push(grdpFilePath);
      continue;
    }

    const grdpFileContent = await localizationUtils.parseFileContent(grdpFilePath);
    const grdpFileLines = grdpFileContent.split('\n');

    let newGrdpFileContent = '';
    const IDSRegex = new RegExp(`"(${localizationUtils.IDSPrefix}.*?)"`);
    for (let i = 0; i < grdpFileLines.length; i++) {
      const grdpLine = grdpFileLines[i];
      const match = grdpLine.match(IDSRegex);
      // match[0]: full match
      // match[1]: message IDS key
      if (match) {
        const ids = match[1];
        const stringsToAddRemaining = [];
        for (const stringObj of stringsToAdd) {
          // Insert the new <message> in sorted order.
          if (ids > stringObj.ids)
            newGrdpFileContent += localizationUtils.createGrdpMessage(stringObj.ids, stringObj);
          else
            stringsToAddRemaining.push(stringObj);
        }
        stringsToAdd = stringsToAddRemaining;
      } else if (grdpLine.includes(grdpFileEnd)) {
        // Just hit the end tag, so insert any remaining <message>s.
        for (const stringObj of stringsToAdd)
          newGrdpFileContent += localizationUtils.createGrdpMessage(stringObj.ids, stringObj);
      }
      newGrdpFileContent += grdpLine;
      if (i < grdpFileLines.length - 1)
        newGrdpFileContent += '\n';
    }

    promises.push(writeFileAsync(grdpFilePath, newGrdpFileContent));
  }
  promises.push(localizationUtils.addChildGRDPFilePathsToGRD(grdpFilePathsToAdd.sort()));
  await Promise.all(promises);
  return true;
}

// Return true if any resources are updated
async function modifyResourcesInGRDP() {
  const messagesToModify = checkLocalizedStrings.getIDSKeysToModify();
  if (messagesToModify.size === 0)
    return false;

  const grdpToMessages = mapGRDPFilePathToMessages(messagesToModify);
  const promises = [];
  for (const [grdpPath, messages] of grdpToMessages) {
    let fileContent = await localizationUtils.parseFileContent(grdpPath);
    for (const message of messages) {
      const idsRegex = new RegExp(`name="${message.actualIDSKey}"`);
      fileContent = fileContent.replace(idsRegex, `name="${message.ids}"`);
    }
    promises.push(writeFileAsync(grdpPath, fileContent));
  }
  await Promise.all(promises);
  return true;
}

// Return true if any resources are removed
async function removeResourcesFromGRDP(keysToRemoveFromGRD) {
  function indexOfFirstMatchingMessage(line, messages) {
    for (let i = 0; i < messages.length; i++) {
      const message = messages[i];
      const match =
          line.match(new RegExp(`<message[^>]*name="${message.ids}"[^>]*desc="${message.description}"[^>]*>`));
      if (match)
        return i;
    }
    return -1;
  }

  if (keysToRemoveFromGRD.size === 0)
    return false;

  const grdpToMessages = mapGRDPFilePathToMessages(keysToRemoveFromGRD);
  const promises = [];
  for (const [grdpFilePath, messages] of grdpToMessages) {
    let newGrdpFileContent = '';
    const grdpFileContent = await localizationUtils.parseFileContent(grdpFilePath);
    const grdpFileLines = grdpFileContent.split('\n');

    for (let i = 0; i < grdpFileLines.length; i++) {
      const index = indexOfFirstMatchingMessage(grdpFileLines[i], messages);
      if (index === -1) {
        newGrdpFileContent += grdpFileLines[i];
        if (i < grdpFileLines.length - 1)
          newGrdpFileContent += '\n';
        continue;
      }

      messages.splice(index, 1);
      while (!grdpFileLines[i].includes('</message>'))
        i++;
    }

    promises.push(writeFileAsync(grdpFilePath, newGrdpFileContent));
  }
  await Promise.all(promises);
  return true;
}

// Given a map from IDS key to a list of messages, return a map
// from grdp file path to a list of messages with a new property
// `ids` set to the key.
function mapGRDPFilePathToMessages(keyToMessages) {
  const grdpFilePathToMessages = new Map();
  for (const [ids, messages] of keyToMessages) {
    for (const message of messages) {
      if (!grdpFilePathToMessages.has(message.grdpPath))
        grdpFilePathToMessages.set(message.grdpPath, []);

      message.ids = ids;
      grdpFilePathToMessages.get(message.grdpPath).push(message);
    }
  }
  return grdpFilePathToMessages;
}
