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

import 'package:collection/collection.dart';

import 'codegen_dart.dart';

export 'meta_model_cleaner.dart';
export 'meta_model_reader.dart';

bool isLiteralType(TypeBase t) => t is LiteralType;

/// Whether this type is the equivalent of 'Object?' and may also be omitted
/// from JSON ("undefined").
bool isNullableAnyType(TypeBase t) =>
    resolveTypeAlias(t).dartTypeWithTypeArgs == 'Object?';

bool isNullType(TypeBase t) =>
    resolveTypeAlias(t).dartTypeWithTypeArgs == 'Null';

/// Whether this type is the equivalent of (non-nullable) 'Object'.
bool isObjectType(TypeBase t) =>
    resolveTypeAlias(t).dartTypeWithTypeArgs == 'Object';

class ArrayType extends TypeBase {
  final TypeBase elementType;

  ArrayType(this.elementType);

  @override
  String get dartType => 'List';
  @override
  String get typeArgsString => '<${elementType.dartTypeWithTypeArgs}>';
}

/// A constant value parsed from the LSP JSON model.
///
/// Used for well-known values in the spec, such as request Method names and
/// error codes.
class Constant extends Member with LiteralValueMixin {
  TypeBase type;
  String value;
  Constant({
    required super.name,
    super.comment,
    required this.type,
    required this.value,
  });

  String get valueAsLiteral => _asLiteral(value);
}

/// A field parsed from the LSP JSON model.
class Field extends Member {
  final TypeBase type;
  final bool allowsNull;
  final bool allowsUndefined;
  Field({
    required super.name,
    super.comment,
    required this.type,
    required this.allowsNull,
    required this.allowsUndefined,
  });
}

class FixedValueField extends Field {
  final String value;
  FixedValueField({
    required super.name,
    super.comment,
    required this.value,
    required super.type,
    required super.allowsNull,
    required super.allowsUndefined,
  });
}

/// An interface/class parsed from the LSP JSON model.
class Interface extends LspEntity {
  final List<TypeReference> baseTypes;
  final List<Member> members;

  Interface({
    required super.name,
    super.comment,
    this.baseTypes = const [],
    required this.members,
  }) {
    baseTypes.sortBy((type) => type.dartTypeWithTypeArgs.toLowerCase());
    members.sortBy((member) => member.name.toLowerCase());
  }

  Interface.inline(String name, List<Member> members)
      : this(name: name, members: members);
}

/// A type parsed from the LSP JSON model that has a singe literal value.
class LiteralType extends TypeBase with LiteralValueMixin {
  final TypeBase type;
  final String _literal;

  LiteralType(this.type, this._literal);

  @override
  String get dartType => type.dartType;

  @override
  String get typeArgsString => type.typeArgsString;

  @override
  String get uniqueTypeIdentifier => '$_literal:${super.uniqueTypeIdentifier}';

  String get valueAsLiteral => _asLiteral(_literal);
}

/// A special class of Union types where the values are all literals of the same
/// type.
///
/// This allows the Dart field for this type to be the the common base type
/// rather than an EitherX<>.
class LiteralUnionType extends UnionType {
  final List<LiteralType> literalTypes;

  LiteralUnionType(this.literalTypes) : super(literalTypes);

  @override
  String get dartType => types.first.dartType;

  @override
  String get typeArgsString => types.first.typeArgsString;
}

mixin LiteralValueMixin {
  /// Returns [value] as the literal Dart code required to represent this value.
  String _asLiteral(String value) {
    if (num.tryParse(value) == null) {
      // Add quotes around strings.
      final prefix = value.contains(r'$') ? 'r' : '';
      return "$prefix'$value'";
    } else {
      return value;
    }
  }
}

/// Base class for named entities (both classes/interfaces and members) parsed
/// from the LSP JSON model.
abstract class LspEntity {
  final String name;
  final String? comment;
  final bool isDeprecated;
  LspEntity({
    required this.name,
    required this.comment,
  }) : isDeprecated = comment?.contains('@deprecated') ?? false;
}

/// An enum parsed from the LSP JSON model.
class LspEnum extends LspEntity {
  final TypeBase typeOfValues;
  final List<Member> members;
  LspEnum({
    required super.name,
    super.comment,
    required this.typeOfValues,
    required this.members,
  }) {
    members.sortBy((member) => member.name.toLowerCase());
  }
}

class LspMetaModel {
  final List<LspEntity> types;
  final List<String> methods;

  LspMetaModel({required this.types, required this.methods});
}

/// A [Map] type parsed from the LSP JSON model.
class MapType extends TypeBase {
  final TypeBase indexType;
  final TypeBase valueType;

  MapType(this.indexType, this.valueType);

  @override
  String get dartType => 'Map';

  @override
  String get typeArgsString =>
      '<${indexType.dartTypeWithTypeArgs}, ${valueType.dartTypeWithTypeArgs}>';
}

/// Base class for members ([Constant] and [Fields]s) parsed from the LSP JSON
/// model.
abstract class Member extends LspEntity {
  Member({
    required super.name,
    super.comment,
  });
}

class NullableType extends TypeBase {
  final TypeBase baseType;

  NullableType(this.baseType);

  @override
  String get dartType => baseType.dartType;

  @override
  String get dartTypeWithTypeArgs => '${super.dartTypeWithTypeArgs}?';

  @override
  String get typeArgsString => baseType.typeArgsString;
}

class TypeAlias extends LspEntity {
  final TypeBase baseType;

  /// Whether this alias is just a simple rename and not a name for a more
  /// complex type.
  ///
  /// Renames will be followed when generating code, but other aliases may be
  /// created as `typedef`s.
  final bool isRename;

  TypeAlias({
    required super.name,
    super.comment,
    required this.baseType,
    required this.isRename,
  });
}

/// Base class for a Type parsed from the LSP JSON model.
abstract class TypeBase {
  String get dartType;
  String get dartTypeWithTypeArgs => '$dartType$typeArgsString';

  String get typeArgsString;

  /// A unique identifier for this type. Used for folding types together
  /// (for example two types that resolve to "Object?" in Dart).
  String get uniqueTypeIdentifier => dartTypeWithTypeArgs;
}

/// A reference to a Type by name.
class TypeReference extends TypeBase {
  static final TypeBase Undefined = TypeReference('undefined');
  static final TypeBase Null_ = TypeReference('Null');

  /// Any object (but not null).
  static final TypeBase LspObject = TypeReference('Object');

  /// Any object (or null/undefined).
  static final TypeBase LspAny = NullableType(TypeReference('Object'));
  final String name;
  final List<TypeBase> typeArgs;

  TypeReference(this.name, {this.typeArgs = const []}) {
    if (name == 'Array' || name.endsWith('[]')) {
      throw 'Type should not be used for arrays, use ArrayType instead';
    }
  }

  @override
  String get dartType {
    // Resolve any renames when asked for our type.
    final resolvedType = resolveTypeAlias(this, onlyRenames: true);
    if (resolvedType != this) {
      return resolvedType.dartType;
    }

    const mapping = <String, String>{
      'boolean': 'bool',
      'string': 'String',
      'number': 'num',
      'integer': 'int',
      'null': 'Null',
      // Map decimal to num because clients may sent "1.0" or "1" and we want
      // to consider both valid.
      'decimal': 'num',
      'uinteger': 'int',
      'object': 'Object?',
      // Simplify MarkedString from
      //     string | { language: string; value: string }
      // to just String
      'MarkedString': 'String'
    };

    final typeName = mapping[name] ?? name;
    return typeName;
  }

  @override
  String get typeArgsString {
    // Resolve any renames when asked for our type.
    final resolvedType = resolveTypeAlias(this, onlyRenames: true);
    if (resolvedType != this) {
      return resolvedType.typeArgsString;
    }

    return typeArgs.isNotEmpty
        ? '<${typeArgs.map((t) => t.dartTypeWithTypeArgs).join(', ')}>'
        : '';
  }
}

/// A union type parsed from the LSP JSON model.
///
/// Union types will be represented in Dart using a custom `EitherX<A, B, ...>`
/// class.
class UnionType extends TypeBase {
  final List<TypeBase> types;

  UnionType(this.types) {
    // Ensure types are always sorted alphabetically to simplify sharing code
    // because `Either2<A, B>` and `Either2<B, A>` are not the same.
    types.sortBy((type) => type.dartTypeWithTypeArgs.toLowerCase());
  }

  @override
  String get dartType {
    if (types.length > 4) {
      throw 'Unions of more than 4 types are not supported.';
    }
    return 'Either${types.length}';
  }

  @override
  String get typeArgsString {
    final typeArgs = types.map((t) => t.dartTypeWithTypeArgs).join(', ');
    return '<$typeArgs>';
  }
}
