// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// TODO(dantup): Regex seemed like a good choice when parsing the first few...
// maybe it's not so great now. We should parse this properly if it turns out
// there are issues with what we have here.
const String _blockBody = r'\{([\s\S]*?)\s*\n\s*\}';
const String _comment = r'(?:\/\*\*((?:[\S\s](?!\*\/))+?)\s\*\/)?\s*';

List<ApiItem> extractAllTypes(List<String> code) {
  return extractTypes(code.join('\n'));
}

List<ApiItem> extractTypes(String code) {
  final types = ApiItem.extractFrom(code);
  _removeUnwantedTypes(types);
  return types;
}

/// Removes types that are in the spec that we don't want.
void _removeUnwantedTypes(List<ApiItem> types) {
  // These types are not used for v3.0 (Feb 2017) and by dropping them we don't
  // have to handle any cases where both a namespace and interfaces are declared
  // with the same name.
  types.removeWhere((item) => item.name == 'InitializeError');
}

String _cleanComment(String comment) {
  if (comment == null) {
    return null;
  }
  final _commentLinePrefixes = new RegExp(r'\n\s*\* ?');
  final _nonConcurrentNewlines = new RegExp(r'\n(?![\n\s\-*])');
  final _newLinesThatRequireReinserting = new RegExp(r'\n (\w)');
  // Remove any Windows newlines from the source.
  comment = comment.replaceAll('\r', '');
  // Remove the * prefixes.
  comment = comment.replaceAll(_commentLinePrefixes, '\n');
  // Remove and newlines that look like wrapped text.
  comment = comment.replaceAll(_nonConcurrentNewlines, ' ');
  // The above will remove one of the newlines when there are two, so we need
  // to re-insert newlines for any block that starts immediately after a newline.
  comment = comment.replaceAllMapped(
      _newLinesThatRequireReinserting, (m) => '\n\n${m.group(1)}');
  return comment.trim();
}

List<String> _parseTypes(String baseTypes, String sep) {
  // Special case for a single complicated type we can't parse easily...
  if (baseTypes ==
      '(TextDocumentEdit[] | (TextDocumentEdit | CreateFile | RenameFile | DeleteFile)[])') {
    return ['FileOperation[]'];
  }
  return baseTypes?.split(sep)?.map((t) => t.trim())?.toList() ?? [];
}

/// Base class for Interface, Field, Constant, etc. parsed from the LSP spec.
abstract class ApiItem {
  String name, comment;
  bool isDeprecated;
  ApiItem(this.name, String comment)
      : comment = _cleanComment(comment),
        isDeprecated = comment?.contains('@deprecated') ?? false;

  static List<ApiItem> extractFrom(String code) {
    List<ApiItem> types = [];
    types.addAll(Interface.extractFrom(code));
    types.addAll(Namespace.extractFrom(code));
    types.addAll(TypeAlias.extractFrom(code));
    return types;
  }
}

/// A Constant parsed from the LSP spec.
class Const extends Member {
  final String type, value;
  Const(String name, String comment, this.type, this.value)
      : super(name, comment);

  static List<Const> extractFrom(String code) {
    final RegExp _constPattern = new RegExp(_comment +
        r'''(?:export\s+)?const\s+(\w+)(?::\s+([\w\[\]'".-]+?))?\s*=\s*([\w\[\]'".-]+)\s*(?:;|$)''');

    final consts = _constPattern.allMatches(code).map((m) {
      final String comment = m.group(1);
      final String name = m.group(2);
      final String type = m.group(3);
      final String value = m.group(4);
      return new Const(name, comment, type, value);
    }).toList();
    return consts;
  }

  static List<Const> extractFromEnumValue(String code) {
    final RegExp _constPattern =
        new RegExp(_comment + r'''(\w+)\s*=\s*([\w\[\]'".-]+)\s*(?:,|$)''');

    final consts = _constPattern.allMatches(code).map((m) {
      final String comment = m.group(1);
      final String name = m.group(2);
      final String value = m.group(3);
      return new Const(name, comment, null, value);
    }).toList();
    return consts;
  }
}

/// A Field for an Interface parsed from the LSP spec.
class Field extends Member {
  final List<String> types;
  final bool allowsNull, allowsUndefined;
  Field(String name, String comment, this.types, this.allowsNull,
      this.allowsUndefined)
      : super(name, comment);

  static List<Field> extractFrom(String interfaceName, String code) {
    final RegExp _fieldPattern = new RegExp(
        _comment + r'([\w\[\]]+\??)\s*:\s*([\w\[\] \|\{\}\(\):;]+)\s*(?:;|$)');

    final fields = _fieldPattern.allMatches(code).where((m) {
      // Skip over the indexer in FormattingOptions since we don't need this
      // (for now) and it's complicated to represent.
      if (m.group(0).contains('[key: string]: boolean | number | string;')) {
        return false;
      }
      return true;
    }).map((m) {
      String comment = m.group(1);
      String name = m.group(2);
      String typesString = m.group(3).trim();
      // Our regex may result in semicolons on the end...
      // TODO(dantup): Fix this, or make a simple parser.
      if (typesString.endsWith(';')) {
        typesString = typesString.substring(0, typesString.length - 1);
      }
      // Some fields have weird comments like this in the spec:
      //     {@link MessageType}
      // These seem to be the correct type of the field, while the field is
      // marked with number.
      if (comment != null) {
        final RegExp _linkTypePattern = new RegExp(r'See \{@link (\w+)\}\.?');
        final linkTypeMatch = _linkTypePattern.firstMatch(comment);
        if (linkTypeMatch != null) {
          typesString = linkTypeMatch.group(1);
          comment = comment.replaceAll(_linkTypePattern, '');
        }
      }
      List<String> types = _parseTypes(typesString, '|');
      final bool allowsNull = types.contains('null');
      if (allowsNull) {
        types.remove('null');
      }
      final bool allowsUndefined = name.endsWith('?');
      if (allowsUndefined) {
        name = name.substring(0, name.length - 1);
      }
      // Perform simple type improvements for enums values that are typed as
      // num/string in the spec but are enums.
      // the spec.
      if (types.length == 1) {
        types[0] = _getImprovedType(interfaceName, name) ?? types[0];
      }
      return new Field(name, comment, types, allowsNull, allowsUndefined);
    }).toList();
    return fields;
  }
}

/// An Interface parsed from the LSP spec.
class Interface extends ApiItem {
  final List<String> baseTypes;
  final List<Member> members;
  Interface(String name, String comment, this.baseTypes, this.members)
      : super(name, comment);

  static List<Interface> extractFrom(String code) {
    final RegExp _interfacePattern = new RegExp(_comment +
        r'(?:export\s+)?(?:interface|class)\s+(\w+)(?:\s+extends\s+([\w, ]+?))?\s*' +
        _blockBody);

    final interfaces = _interfacePattern.allMatches(code).map((match) {
      final String comment = match.group(1);
      final String name = match.group(2);
      final List<String> baseTypes = _parseTypes(match.group(3), ',');
      final String body = match.group(4);
      final List<Member> members = Member.extractFrom(name, body);

      // Add any special base classes we've added to simplify types.
      baseTypes.addAll(_getSpecialBaseClasses(name));

      return new Interface(name, comment, baseTypes, members);
    }).toList();
    return interfaces;
  }
}

List<String> _getSpecialBaseClasses(String name) {
  const fileOperationTypes = [
    'TextDocumentEdit',
    'CreateFile',
    'RenameFile',
    'DeleteFile'
  ];
  if (fileOperationTypes.contains(name)) {
    return ['FileOperation'];
  } else {
    return [];
  }
}

/// Fixes up some enum types that are not as specific as they could be in the
/// spec. For example, Diagnostic.severity is typed "number" but can be mapped
/// to the DiagnosticSeverity enum class.
String _getImprovedType(String interfaceName, String fieldName) {
  const Map<String, Map<String, String>> _improvedTypeMappings = {
    "Diagnostic": {
      "severity": "DiagnosticSeverity",
    },
    "TextDocumentSyncOptions": {
      "change": "TextDocumentSyncKind",
    },
    "FileSystemWatcher": {
      "kind": "WatchKind",
    },
    "CompletionItem": {
      "kind": "CompletionItemKind",
    },
    "DocumentHighlight": {
      "kind": "DocumentHighlightKind",
    },
    "FoldingRange": {
      "kind": "FoldingRangeKind",
    },
  };

  final interface = _improvedTypeMappings[interfaceName];

  return interface != null ? interface[fieldName] : null;
}

/// A Field or Constant parsed from the LSP type.
abstract class Member extends ApiItem {
  Member(String name, String comment) : super(name, comment);

  static List<Member> extractFrom(String interfaceName, String code) {
    List<Member> members = [];
    members.addAll(Field.extractFrom(interfaceName, code));
    members.addAll(Const.extractFrom(code));
    return members;
  }
}

/// An Enum or Namsepace containing constants parsed from the LSP spec.
class Namespace extends ApiItem {
  final List<Member> members;
  Namespace(String name, String comment, this.members) : super(name, comment);

  static List<Namespace> extractFrom(String code) {
    final enums = <Namespace>[];
    enums.addAll(_extractNamespacesFrom(code));
    enums.addAll(_extractEnumsFrom(code));
    return enums;
  }

  static List<Namespace> _extractNamespacesFrom(String code) {
    final RegExp _namespacePattern = new RegExp(
        _comment + r'(?:export\s+)?namespace\s+(\w+)\s*' + _blockBody);

    final namespaces = _namespacePattern.allMatches(code).map((match) {
      final String comment = match.group(1);
      final String name = match.group(2);
      final String body = match.group(3);
      final List<Member> members = Member.extractFrom(name, body);
      return new Namespace(name, comment, members);
    }).toList();
    return namespaces;
  }

  static List<Namespace> _extractEnumsFrom(String code) {
    final RegExp _namespacePattern =
        new RegExp(_comment + r'(?:export\s+)?enum\s+(\w+)\s*' + _blockBody);

    final namespaces = _namespacePattern.allMatches(code).map((match) {
      final String comment = match.group(1);
      final String name = match.group(2);
      final String body = match.group(3);

      final List<Member> members = Const.extractFromEnumValue(body);
      return new Namespace(name, comment, members);
    }).toList();
    return namespaces;
  }
}

/// A type alias parsed from the LSP spec.
class TypeAlias extends ApiItem {
  final String baseType;
  TypeAlias(name, comment, this.baseType) : super(name, comment);

  static List<TypeAlias> extractFrom(String code) {
    final RegExp _typeAliasPattern =
        new RegExp(_comment + r'type\s+([\w]+)\s+=\s+([\w\[\]]+)\s*;');

    final typeAliases = _typeAliasPattern.allMatches(code).map((match) {
      final String comment = match.group(1);
      final String name = match.group(2);
      final String baseType = match.group(3);
      return new TypeAlias(name, comment, baseType);
    }).toList();
    return typeAliases;
  }
}
