// Copyright 2021 The Chromium Authors
// 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 'node:fs';
import * as path from 'node:path';
import {fileURLToPath} from 'node:url';

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

export function clearState() {
  methods.clear();
  includes.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 thing
 * */
export function walkRoot(thing) {
  switch (thing.type) {
    case 'interface':
      walkInterface(thing);
      break;
    case 'interface mixin':
    case 'namespace':
      walkMembers(thing);
      break;
    case 'includes':
      walkIncludes(thing);
      break;
  }
}

/**
 * @param thing
 * */
function walkIncludes(thing) {
  if (includes.has(thing.includes)) {
    includes.get(thing.includes).push(thing.target);
  } else {
    includes.set(thing.includes, [thing.target]);
  }
}
/**
 * @param 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 thing
 * */
function walkMembers(thing) {
  thing.members.forEach(member => {
    if (member.type === 'operation') {
      handleOperation(member);
    }
  });
}

/**
 * @param member
 * */
function handleOperation(member) {
  storeMethod(member.parent.name, member.name, member.arguments.map(argName));
}

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

/**
 * @param parent
 * @param name
 * @param 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 {
      const receiversMap = new Map();
      for (const [parent, signatures] of method) {
        const receivers = receiversMap.get(JSON.stringify(signatures)) || new Set();
        if (includes.has(parent)) {
          includes.get(parent).forEach(receiver => receivers.add(receiver));
        } else {
          receivers.add(parent);
        }
        receiversMap.set(JSON.stringify(signatures), receivers);
      }
      for (const [signatures, receivers] of receiversMap) {
        functions.push({name, signatures: JSON.parse(signatures), receivers: Array.from(receivers)});
      }
    }
  }
  const output = `export interface NativeFunctionValue {
  name: string;
  signatures: string[][];
  receivers?: string[];
}

export const NativeFunctions: readonly NativeFunctionValue[] = [\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.ts', import.meta.url)).pathname,
      `// Copyright 2020 The Chromium Authors
// 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))}

// clang-format off

${output}
`);
}
