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

// This generates a language definition file because writing it by hand is too hard.

// Format of language definition JSON
const tmSchema = 'https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json';
type TmCaptures = Record<string, { name: string }>;
interface TmIncludePattern { include: string }
interface TmMatchPattern {
  name?: string;
  match: string;
  captures?: TmCaptures;
}
interface TmBlockPattern {
  name?: string;
  begin: string;
  beginCaptures?: TmCaptures;
  end: string;
  endCaptures?: TmCaptures;
  patterns: TmPattern[];
}
type TmPattern = TmIncludePattern | TmMatchPattern | TmBlockPattern;
interface TmLanguage {
  $schema: string;
  name: string;
  scopeName: string;
  patterns: TmPattern[];
  repository: Record<string, { patterns: TmPattern[] }>;
}

class NamedPattern {
  readonly re: string;
  readonly names: string[];
  constructor(re: string, names?: string[]) {
    this.re = re;
    this.names = names ?? [];
    // Hack to only validate if there are no unresolved recursive groups
    const recursiveRE = /\\g<(.*?)>/g;
    let match;
    while ((match = recursiveRE.exec(re)) !== null) {
      if (!re.includes(`(?<${match[1]}>`)) {
        // Group definition not found, can't validate yet.
        return;
      }
    }
    this.validate();
  }

  validate() {
    // TODO(fxbug.dev/119360): reenable this
    // const groupCount = new OnigRegExp(this.re + '|').searchSync('')!.length - 1;
    // if (groupCount !== this.names.length) {
    //   throw new Error(
    //     `Found ${groupCount} but expected ${this.names.length} groups in ${this.re}`
    //   );
    // }
  }

  toString() {
    return this.re;
  }

  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  assert(_s: string) {
    // TODO(fxbug.dev/119360): reenable this
    // const re = new OnigRegExp(this.re);
    // const m = re.searchSync(s);
    // if (!m) {
    //   throw Error(
    //     `${JSON.stringify(s)} did not match pattern ${JSON.stringify(this.re)}`
    //   );
    // }
    // const c = m[0];
    // if (c.index !== 0 || c.start !== 0 || c.length !== s.length) {
    //   throw Error(
    //     `${JSON.stringify(s)} did not fully match pattern ${JSON.stringify(
    //       this.re
    //     )}, only matched ${JSON.stringify(m[0])}`
    //   );
    // }
  }
}

/**
 * Create a dictionary of capture group names: <captureIdx, nameId>
 * @param pattern input pattern
 * @returns dictionary
 */
function getCaptures(pattern: Pattern): TmCaptures {
  const captures: Record<string, { name: string }> = {};
  const names = getPatternNames(pattern);
  for (let i = 0; i < names.length; i++) {
    captures[`${i + 1}`] = { name: names[i] };
  }
  return captures;
}

/**
 * Create a match pattern for the output json syntax.
 * @param name
 * @param pattern
 * @returns pattern struct for the output json.
 */
function match(name: string, pattern: Pattern): TmMatchPattern {
  return {
    name: `${name}.fuchsia-log`,
    match: pattern.toString(),
    captures: getCaptures(pattern),
  };
}

///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////

type Pattern = NamedPattern | string;

/** Return the names of the groups in the pattern. */
function getPatternNames(pat: Pattern | Pattern[]): string[] {
  if (pat instanceof Array) {
    return pat.map(getPatternNames).reduce((prev, names) => [...(prev || []), ...names]);
  }
  if (pat instanceof NamedPattern) {
    return pat.names;
  } else {
    return [];
  }
}

/**
 * Utility to create a NamedPattern by concatenating an input pattern array. Output =
 * [prefix + (pat + separator?)* + suffix]
 * @param pats input pattern array.
 * @param prefix
 * @param separator used to concatenate input patterns together.
 * @param suffix
 * @returns the resulting NamedPattern.
 */
function joinPattern(
  pats: Pattern[],
  prefix: string,
  separator: string,
  suffix: string,
): NamedPattern {
  const re = pats.map(p => p.toString()).join(separator);
  return new NamedPattern(prefix + re + suffix, getPatternNames(pats));
}

// NamedPattern Factory.
const patterns = {
  /**
   * Create a non-capturing NamedPattern group that matches one item from the pattern input vector.
   * @param pats pattern input vector
   * @returns NamedPattern.
   */
  oneFrom: function (...pats: Pattern[]): NamedPattern {
    return joinPattern(pats, '(?:', '|', ')');
  },

  /**
   * Create a non-capturing NamedPattern group that matches the input pattern zero or more times.
   * @param pattern
   * @returns NamedPattern
   */
  zeroOrMore: function (pattern: Pattern): NamedPattern {
    return new NamedPattern(`(?:${pattern.toString()})*`, getPatternNames(pattern));
  },

  /**
   * Create a NamedPattern.
   * @param pattern
   * @param name
   * @returns NamedPattern
   */
  named: function (pattern: Pattern, name: string) {
    return new NamedPattern(`(${pattern.toString()})`, [name, ...getPatternNames(pattern)]);
  },
};

///////////////////////////////////////////////////////////////////////////////////////////////////
// Fuchsia Log language description.
///////////////////////////////////////////////////////////////////////////////////////////////////

const TIMESTAMP_TAG = patterns.named('\\[[0-9]+[.][0-9]+\\]', 'constant.numeric');
const USER_TAGS = patterns.named(patterns.zeroOrMore('\\[([^\\]]*)\\]'), 'entity.name.type');

const TAGS = new NamedPattern(
  `^${TIMESTAMP_TAG.toString()}${USER_TAGS.toString()}`,
  getPatternNames([TIMESTAMP_TAG, USER_TAGS]),
);

const logLevels = [
  ' TRACE: ',
  ' DEBUG: ',
  ' INFO: ',
  patterns.named(' WARN: ', 'string.quoted'),
  patterns.named(' ERROR: ', 'string.quoted'),
  patterns.named(' FATAL: ', 'string.quoted'),
];

const SEVERITY = patterns.oneFrom(...logLevels);

TIMESTAMP_TAG.assert('[00047.419145]');

USER_TAGS.assert('[pkg-resolver]');
USER_TAGS.assert('[agents:agent-b05def7e]');
USER_TAGS.assert('[pkg-resolver][agents:agent-b05def7e]');

TAGS.assert('[00792.409891][agents:agent-b05def7e]');
TAGS.assert('[03723.724755][netstack][DHCP]');

SEVERITY.assert('WARN');

const tmLanguage: TmLanguage = {
  $schema: tmSchema,
  name: 'Fuchsia Log',
  scopeName: 'source.fuchsia-log',
  patterns: [
    match('meta.tags', TAGS),
    match('meta.severity', SEVERITY),
  ],
  repository: {},
};

export default tmLanguage;
