// Copyright 2018 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.

import { OnigRegExp } from "oniguruma";

// Format of language definition JSON
const tmSchema =
  "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json";
type TmCaptures = { [k: string]: { name: string } };
type TmIncludePattern = { include: string };
type TmMatchPattern = {
  name?: string;
  match: string;
  captures?: TmCaptures;
};
type TmBlockPattern = {
  name?: string;
  begin: string;
  beginCaptures?: TmCaptures;
  end: string;
  endCaptures?: TmCaptures;
  patterns: TmPattern[];
};
type TmPattern = TmIncludePattern | TmMatchPattern | TmBlockPattern;
type TmLanguage = {
  $schema: string;
  name: string;
  scopeName: string;
  patterns: TmPattern[];
  repository: {
    [key: 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 recursive_re = /\\g<(.*?)>/g;
    let match;
    while ((match = recursive_re.exec(re)) !== null) {
      if (!re.includes(`(?<${match[1]}>`)) {
        // Group definition not found, can't validate yet.
        return;
      }
    }
    this.validate();
  }

  validate() {
    const num_groups = new OnigRegExp(this.re + "|").searchSync("")!.length - 1;
    if (num_groups !== this.names.length) {
      throw new Error(
        `Found ${num_groups} but expected ${this.names.length} groups in ${
          this.re
        }`
      );
    }
  }

  toString() {
    return this.re;
  }

  assert(s: string) {
    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])}`
      );
    }
  }
}

function _captures(pattern: Pattern): TmCaptures {
  const captures: { [k: string]: { name: string } } = {};
  const names = _names(pattern);
  for (let i = 0; i < names.length; i++) {
    captures[`${i + 1}`] = { name: names[i] };
  }
  return captures;
}

function include(name: string): TmIncludePattern {
  return { include: `#${name}` };
}

function match(name: string, pat: Pattern): TmMatchPattern {
  return {
    name: `${name}.fidl`,
    match: pat.toString(),
    captures: _captures(pat)
  };
}

function anonMatch(pattern: Pattern | TmPattern): TmPattern {
  if (pattern instanceof String) {
    return {
      match: pattern.toString()
    };
  }
  if (pattern instanceof NamedPattern) {
    return {
      match: pattern.toString(),
      captures: _captures(pattern)
    };
  }
  return pattern;
}

function block(args: {
  name: string;
  begin: Pattern;
  end: Pattern;
  patterns: Array<Pattern | TmPattern>;
}): TmBlockPattern {
  const tmPatterns: TmPattern[] = args.patterns.map(anonMatch);
  return {
    name: `${args.name}.fidl`,
    begin: args.begin.toString(),
    beginCaptures: _captures(args.begin),
    end: args.end.toString(),
    endCaptures: _captures(args.end),
    patterns: tmPatterns
  };
}

type Pattern = NamedPattern | String;

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

function _join(
  pats: Pattern[],
  prefix: string,
  separator: string,
  suffix: string
): NamedPattern {
  const re = pats.map(p => p.toString()).join(separator);
  return new NamedPattern(prefix + re + suffix, _names(pats));
}

/**
 * Create a new pattern consisting of adjacent input patterns optionally separated by whitespace.
 * @param pats Patterns
 */
function seq(...pats: Pattern[]): NamedPattern {
  return _join(pats, "", "\\s*", "");
}

function one_of(...pats: Pattern[]): NamedPattern {
  return _join(pats, "(?:", "|", ")");
}

function one_of_words(...words: string[]) {
  return word(one_of(...words));
}

function optional(pat: Pattern): NamedPattern {
  return new NamedPattern(`(?:${pat})?`, _names(pat));
}

function word(word: Pattern): NamedPattern {
  return new NamedPattern(`\\b${word}\\b`, _names(word));
}

function named(pat: Pattern, name: string) {
  return new NamedPattern(`(${pat})`, [name, ..._names(pat)]);
}

function recursive_group(
  context_name: string,
  group_name: string,
  body: Pattern
): NamedPattern {
  return new NamedPattern(`(?<${group_name}>${body})`, [
    context_name,
    ..._names(body)
  ]);
}

function recursive_group_reference(group_name: string): Pattern {
  return String.raw`\g<${group_name}>`;
}

const NUMERIC_LITERAL = named(
  "-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:0(?:b|B)[01]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)\\b",
  "constant.numeric"
);
const BOOLEAN_LITERAL = named(
  one_of_words("true", "false"),
  "constant.language"
);
const STRING_LITERAL = named('"(?:[^\\"]|\\.)*"', "string.quoted.double");
const LITERAL = one_of(NUMERIC_LITERAL, BOOLEAN_LITERAL, STRING_LITERAL);

const IDENTIFIER = "@?\\b[a-zA-Z_][0-9a-zA-Z_]*\\b";
const COMPOUND_IDENTIFIER = new NamedPattern(
  `${IDENTIFIER}(?:\\.${IDENTIFIER})*`
);

const CONSTANT = one_of(LITERAL, COMPOUND_IDENTIFIER);
const NUMERIC_CONSTANT = one_of(NUMERIC_LITERAL, COMPOUND_IDENTIFIER);

const NULLABLE = named("[?]", "punctuation.nullable");

function nullable(pat: Pattern): Pattern {
  return seq(pat, NULLABLE);
}

function angle_brackets(contents: Pattern) {
  const scope = "punctuation.bracket.angle";
  return seq(named("<", scope), contents, named(">", scope));
}

function keyword(keyword: string, name: string = "keyword.control") {
  return word(named(keyword, name));
}

function type_keyword(type_name: string) {
  return keyword(type_name, "storage.type.basic");
}

function separator(sep: string) {
  return named(sep, "punctuation.separator");
}

const primitive_types = [
  "bool",
  "float32",
  "float64",
  "int8",
  "int16",
  "int32",
  "int64",
  "uint8",
  "uint16",
  "uint32",
  "uint64"
];
const handle_types = [
  "bti",
  "channel",
  "debuglog",
  "event",
  "eventpair",
  "fifo",
  "guest",
  "interrupt",
  "job",
  "port",
  "process",
  "profile",
  "resource",
  "socket",
  "thread",
  "timer",
  "vmar",
  "vmo"
];
const PRIMITIVE_TYPE = named(
  one_of_words(...primitive_types),
  "storage.type.basic"
);
const HANDLE_TYPE = named(
  nullable(
    seq(word("handle"), optional(angle_brackets(one_of_words(...handle_types))))
  ),
  "storage.type.basic"
);
const EOL = new NamedPattern("(;)", ["punctuation.terminator"]);
const LIBRARY_NAME = named(COMPOUND_IDENTIFIER, "entity.name.type");
const LOCAL_TYPE = named(IDENTIFIER, "entity.name.type");
const VARIABLE = named(IDENTIFIER, "variable");

const LOOKAHEAD_IDENTIFIER = "(?=[a-zA-Z_@])";

const ATTRIBUTE = seq(
  named(IDENTIFIER, "support.variable"),
  optional(seq("=", STRING_LITERAL))
);

const ATTRIBUTES = block({
  name: "meta.attrbutes",
  begin: String.raw`\[`,
  end: String.raw`\]`,
  patterns: [ATTRIBUTE]
});

const TYPE_CONSTRAINT = seq(
  separator(":"),
  one_of(NUMERIC_LITERAL, COMPOUND_IDENTIFIER)
);

const TYPE_CONSTRUCTOR = recursive_group(
  "entity.name.type",
  "type-constructor",
  seq(
    one_of(
      PRIMITIVE_TYPE,
      HANDLE_TYPE,
      seq(
        one_of(
          type_keyword("vector"),
          type_keyword("array"),
          type_keyword("request"),
          named(word("string"), "storage.type.basic"),
          COMPOUND_IDENTIFIER
        ),
        optional(angle_brackets(recursive_group_reference("type-constructor"))),
        optional(TYPE_CONSTRAINT),
        optional(NULLABLE)
      )
    )
  )
);

// Checks

COMPOUND_IDENTIFIER.assert("foo");
COMPOUND_IDENTIFIER.assert("foo_bar");
COMPOUND_IDENTIFIER.assert("foo.bar.baz");

TYPE_CONSTRUCTOR.assert("string");
TYPE_CONSTRUCTOR.assert("string?");
TYPE_CONSTRUCTOR.assert("string:2");
TYPE_CONSTRUCTOR.assert("string:MAX_LEN");
TYPE_CONSTRUCTOR.assert("string:2?");
TYPE_CONSTRUCTOR.assert("string:MAX_LEN?");

NUMERIC_LITERAL.assert("-42");
NUMERIC_LITERAL.assert("0x12345deadbeef");
NUMERIC_LITERAL.assert("0b101110");

TYPE_CONSTRUCTOR.assert("handle");
TYPE_CONSTRUCTOR.assert("handle?");
TYPE_CONSTRUCTOR.assert("handle<socket>");
TYPE_CONSTRUCTOR.assert("handle<debuglog>?");

TYPE_CONSTRUCTOR.assert("foo.bar.myvectoralias<uint8>:8");

// TODO: support attributes
const tmLanguage: TmLanguage = {
  $schema: tmSchema,
  name: "FIDL",
  scopeName: "source.fidl",
  patterns: [
    include("comments"),

    // Library declaration
    match("meta.library", seq(keyword("library"), LIBRARY_NAME, EOL)),

    // Variations of using
    match("meta.library", seq(keyword("using"), LIBRARY_NAME, EOL)),
    match(
      "meta.library",
      seq(keyword("using"), LIBRARY_NAME, keyword("as"), LOCAL_TYPE, EOL)
    ),
    match(
      "meta.library",
      seq(keyword("using"), LOCAL_TYPE, separator("="), TYPE_CONSTRUCTOR, EOL)
    ),

    // Const declaration
    match(
      "meta.const",
      seq(
        keyword("const"),
        one_of(COMPOUND_IDENTIFIER, PRIMITIVE_TYPE),
        named(IDENTIFIER, "variable.constant"),
        separator("="),
        one_of(CONSTANT, NUMERIC_CONSTANT),
        EOL
      )
    ),

    // Protocols
    block({
      name: "meta.protocol-block",
      begin: seq(keyword("protocol"), LOCAL_TYPE, "{"),
      end: "}",
      patterns: [
        ATTRIBUTES,
        seq(keyword("compose"), named(COMPOUND_IDENTIFIER, "entity.name.type")),
        include("method"),
        include("comments")
      ]
    }),

    // Enums
    block({
      name: "meta.enum-block",
      begin: seq(
        keyword("enum"),
        LOCAL_TYPE,
        optional(seq(separator(":"), TYPE_CONSTRUCTOR)),
        "{"
      ),
      end: "}",
      patterns: [include("enum-member"), include("comments")]
    }),

    // Bits
    block({
      name: "meta.bits-block",
      begin: seq(
        keyword("bits"),
        LOCAL_TYPE,
        optional(seq(separator(":"), TYPE_CONSTRUCTOR)),
        "{"
      ),
      end: "}",
      patterns: [include("enum-member"), include("comments")]
    }),

    // Struct
    block({
      name: "meta.struct-block",
      begin: seq(keyword("struct"), LOCAL_TYPE, "{"),
      end: "}",
      patterns: [include("struct-member"), include("comments")]
    }),

    // Table
    block({
      name: "meta.table-block",
      begin: seq(keyword("table"), LOCAL_TYPE, "{"),
      end: "}",
      patterns: [include("table-member"), include("comments")]
    }),

    // Union and XUnion
    block({
      name: "meta.union-block",
      begin: seq(one_of(keyword("union"), keyword("xunion")), LOCAL_TYPE, "{"),
      end: "}",
      patterns: [include("union-member"), include("comments")]
    })
  ],
  repository: {
    comments: {
      patterns: [
        match("invalid.illegal.stray-comment-end", "\\*/.*\\n"),
        match("comment.line.documentation", "///.*\\n"),
        match("comment.line.double-slash", "//.*\\n")
      ]
    },
    method: {
      patterns: [
        block({
          name: "meta.method",
          begin: seq(named(IDENTIFIER, "entity.name.function")),
          end: seq(optional(seq(keyword("error"), TYPE_CONSTRUCTOR)), EOL),
          patterns: [include("method-arguments"), separator("->")]
        }),
        block({
          name: "meta.method.event",
          begin: seq(
            separator("->"),
            named(IDENTIFIER, "entity.name.function"),
            "[(]"
          ),
          end: seq("[)]", EOL),
          patterns: [include("method-argument")]
        })
      ]
    },
    "method-arguments": {
      patterns: [
        block({
          name: "meta.method.arguments",
          begin: "\\(",
          end: "\\)",
          patterns: [include("method-argument")]
        })
      ]
    },
    "method-argument": {
      patterns: [
        block({
          name: "meta.method.argument",
          begin: LOOKAHEAD_IDENTIFIER,
          end: seq(named(IDENTIFIER, "variable.name"), "(?:(?:,)|(?=\\)))"),
          patterns: [TYPE_CONSTRUCTOR, named(IDENTIFIER, "variable.parameter")]
        })
      ]
    },
    "enum-member": {
      patterns: [
        match(
          "meta.enum.member",
          seq(VARIABLE, separator("="), NUMERIC_CONSTANT, EOL)
        )
      ]
    },
    "struct-member": {
      patterns: [
        match("meta.struct.member", seq(TYPE_CONSTRUCTOR, VARIABLE, EOL)),
        match(
          "meta.struct.member",
          seq(TYPE_CONSTRUCTOR, VARIABLE, separator("="), CONSTANT, EOL)
        )
      ]
    },
    "table-member": {
      patterns: [
        match(
          "meta.table.member",
          seq(NUMERIC_LITERAL, separator(":"), TYPE_CONSTRUCTOR, VARIABLE, EOL)
        ),
        match(
          "meta.table.reserved",
          seq(NUMERIC_LITERAL, separator(":"), keyword("reserved"), EOL)
        )
      ]
    },
    "union-member": {
      patterns: [
        match(
          "meta.union.member",
          seq(NUMERIC_LITERAL, separator(":"), TYPE_CONSTRUCTOR, VARIABLE, EOL)
        ),
        match(
          "meta.union.member.reserved",
          seq(NUMERIC_LITERAL, separator(":"), keyword("reserved"), EOL)
        )
      ]
    },
    attributes: {
      patterns: []
    }
  }
};

console.log(JSON.stringify(tmLanguage, null, "    "));
