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

// @ts-check

import * as fs from 'fs';
import * as path from 'path';
import {fileURLToPath} from 'url';

/** @type {Map<string, Map<string, string[][]>>} */
const methods = new Map();

export function clearState() {
  methods.clear();
}

export function parseTSFunction(func, node) {
  if (!func.name.escapedText) {
    return;
  }

  const args = func.parameters
                   .map(p => {
                     let text = p.name.escapedText;
                     if (p.questionToken) {
                       text = '?' + text;
                     }
                     if (p.dotDotDotToken) {
                       text = '...' + text;
                     }
                     return text;
                   })
                   .filter(x => x !== 'this');
  storeMethod(node.name.text, func.name.escapedText, args);
}

/**
 * @param {WebIDL2.IDLRootType} thing
 * */
export function walkRoot(thing) {
  switch (thing.type) {
    case 'interface':
      walkInterface(thing);
      break;
    case 'interface mixin':
    case 'namespace':
      walkMembers(thing);
      break;
  }
}

/**
 * @param {WebIDL2.InterfaceType} thing
 * */
function walkInterface(thing) {
  thing.members.forEach(member => {
    switch (member.type) {
      case 'constructor':
        storeMethod('Window', thing.name, member.arguments.map(argName));
        break;
      case 'operation':
        handleOperation(member);
    }
  });
  const namedConstructor = thing.extAttrs.find(extAttr => extAttr.name === 'NamedConstructor');
  if (namedConstructor && namedConstructor.arguments) {
    storeMethod('Window', namedConstructor.rhs.value, namedConstructor.arguments.map(argName));
  }
}

/**
 * @param {WebIDL2.NamespaceType | WebIDL2.InterfaceMixinType} thing
 * */
function walkMembers(thing) {
  thing.members.forEach(member => {
    if (member.type === 'operation') {
      handleOperation(member);
    }
  });
}

/**
 * @param {WebIDL2.OperationMemberType} member
 * */
function handleOperation(member) {
  storeMethod(
      member.special === 'static' ? (parent.name + 'Constructor') : member.parent.name, member.name,
      member.arguments.map(argName));
}

/**
 * @param {WebIDL2.Argument} a
 * */
function argName(a) {
  let name = a.name;
  if (a.optional) {
    name = '?' + name;
  }
  if (a.variadic) {
    name = '...' + name;
  }
  return name;
}

/**
 * @param {string} parent
 * @param {string} name
 * @param {Array<string>} args
 * */
function storeMethod(parent, name, args) {
  if (!methods.has(name)) {
    methods.set(name, new Map());
  }
  const method = methods.get(name);
  if (!method.has(parent)) {
    method.set(parent, []);
  }
  method.get(parent).push(args);
}

export function postProcess(dryRun = false) {
  for (const name of methods.keys()) {
    // We use the set jsonParents to track the set of different signatures across parent for this function name.
    // If all signatures are identical, we leave out the parent and emit a single NativeFunction entry without receiver.
    const jsonParents = new Set();
    for (const [parent, signatures] of methods.get(name)) {
      signatures.sort((a, b) => a.length - b.length);
      const filteredSignatures = [];
      for (const signature of signatures) {
        const smallerIndex = filteredSignatures.findIndex(smaller => startsTheSame(smaller, signature));
        if (smallerIndex !== -1) {
          filteredSignatures[smallerIndex] = (signature.map((arg, index) => {
            const otherArg = filteredSignatures[smallerIndex][index];
            if (otherArg) {
              return otherArg.length > arg.length ? otherArg : arg;
            }
            if (arg.startsWith('?') || arg.startsWith('...')) {
              return arg;
            }
            return '?' + arg;
          }));
        } else {
          filteredSignatures.push(signature);
        }
      }

      function startsTheSame(smaller, bigger) {
        for (let i = 0; i < smaller.length; i++) {
          const withoutQuestion = str => /[\?]?(.*)/.exec(str)[1];
          if (withoutQuestion(smaller[i]) !== withoutQuestion(bigger[i])) {
            return false;
          }
        }
        return true;
      }

      methods.get(name).set(parent, filteredSignatures);
      jsonParents.add(JSON.stringify(filteredSignatures));
    }
    // If all parents had the same signature for this name, we put a `*` as parent for this entry.
    if (jsonParents.size === 1) {
      methods.set(name, new Map([['*', JSON.parse(jsonParents.values().next().value)]]));
    }
    for (const [parent, signatures] of methods.get(name)) {
      if (signatures.length === 1 && !signatures[0].length) {
        methods.get(name).delete(parent);
      }
    }
    if (methods.get(name).size === 0) {
      methods.delete(name);
    }
  }
  const functions = [];
  for (const [name, method] of methods) {
    if (method.has('*')) {
      // All parents had the same signature so we emit an entry without receiver.
      functions.push({name, signatures: method.get('*')});
    } else {
      for (const [parent, signatures] of method) {
        if (parent.endsWith('Constructor')) {
          functions.push(
              {name, signatures, static: true, receiver: parent.substring(0, parent.length - 'Constructor'.length)});
        } else {
          functions.push({name, signatures, receiver: parent});
        }
      }
    }
  }
  const output = `export const NativeFunctions = [\n${
      functions
          .map(
              entry =>
                  `  {\n${Object.entries(entry).map(kv => `    ${kv[0]}: ${JSON.stringify(kv[1])}`).join(',\n')}\n  }`)
          .join(',\n')}\n];`;

  if (dryRun) {
    return output;
  }

  fs.writeFileSync(
      (new URL('../../front_end/models/javascript_metadata/NativeFunctions.js', import.meta.url)).pathname,
      `// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Generated from ${
          path.relative(path.join(fileURLToPath(import.meta.url), '..', '..'), fileURLToPath(import.meta.url))}

${output}
`);
}
