// Copyright (c) 2019, 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:expect/expect.dart" show Expect;

import "package:kernel/ast.dart" show Component, DartType, Library;

import "package:kernel/class_hierarchy.dart" show ClassHierarchy;

import "package:kernel/core_types.dart" show CoreTypes;

import "package:kernel/text/ast_to_text.dart" show Printer;

import "package:kernel/type_environment.dart"
    show SubtypeCheckMode, TypeEnvironment;

import "kernel_type_parser.dart"
    show KernelEnvironment, KernelFromParsedType, parseLibrary;

import "mock_sdk.dart" show mockSdk;

import "shared_type_tests.dart" show SubtypeTest;

import "type_parser.dart" as type_parser show parse, parseTypeVariables;

const String testSdk = """
typedef Typedef<T> <S>(T*) ->* S*;
typedef VoidFunction () ->* void;
class DefaultTypes<S, T extends Object*, U extends List<S*>*, V extends List<T*>*, W extends Comparable<W*>*, X extends (W*) ->* void, Y extends () ->* W*>;
typedef TestDefaultTypes () ->* DefaultTypes*;
typedef Id<T> T*;
typedef TestSorting ({int* c, int* b, int* a}) ->* void;
class Super implements Comparable<Sub*>;
class Sub extends Super;
class FBound<T extends FBound<T*>*>;
class MixinApplication extends Object with FBound<MixinApplication*>;
""";

const String expectedSdk = """
library core;
import self as self;

typedef Typedef<T extends self::Object* = dynamic> = <S extends self::Object* = dynamic>(T*) →* S*;
typedef VoidFunction = () →* void;
typedef TestDefaultTypes = () →* self::DefaultTypes<dynamic, self::Object*, self::List<dynamic>*, self::List<self::Object*>*, self::Comparable<dynamic>*, (<BottomType>) →* void, () →* self::Comparable<dynamic>*>*;
typedef Id<T extends self::Object* = dynamic> = T*;
typedef TestSorting = ({a: self::int*, b: self::int*, c: self::int*}) →* void;
class Object {
}
class Comparable<T extends self::Object* = dynamic> extends self::Object {
}
class num extends self::Object implements self::Comparable<self::num*> {
}
class int extends self::num {
}
class double extends self::num {
}
class Iterable<T extends self::Object* = dynamic> extends self::Object {
}
class List<T extends self::Object* = dynamic> extends self::Iterable<self::List::T*> {
}
class Future<T extends self::Object* = dynamic> extends self::Object {
}
class FutureOr<T extends self::Object* = dynamic> extends self::Object {
}
class Null extends self::Object {
}
class Function extends self::Object {
}
class String extends self::Object {
}
class bool extends self::Object {
}
class DefaultTypes<S extends self::Object* = dynamic, T extends self::Object* = self::Object*, U extends self::List<self::DefaultTypes::S*>* = self::List<dynamic>*, V extends self::List<self::DefaultTypes::T*>* = self::List<self::Object*>*, W extends self::Comparable<self::DefaultTypes::W*>* = self::Comparable<dynamic>*, X extends (self::DefaultTypes::W*) →* void = (<BottomType>) →* void, Y extends () →* self::DefaultTypes::W* = () →* self::Comparable<dynamic>*> extends self::Object {
}
class Super extends self::Object implements self::Comparable<self::Sub*> {
}
class Sub extends self::Super {
}
class FBound<T extends self::FBound<self::FBound::T*>* = self::FBound<dynamic>*> extends self::Object {
}
class MixinApplication = self::Object with self::FBound<self::MixinApplication*> {
}
""";

Component parseSdk(Uri uri, KernelEnvironment environment) {
  Library library =
      parseLibrary(uri, mockSdk + testSdk, environment: environment);
  StringBuffer sb = new StringBuffer();
  Printer printer = new Printer(sb);
  printer.writeLibraryFile(library);
  Expect.stringEquals(expectedSdk, "$sb");
  return new Component(libraries: <Library>[library]);
}

main() {
  Uri uri = Uri.parse("dart:core");
  KernelEnvironment environment = new KernelEnvironment(uri, uri);
  Component component = parseSdk(uri, environment);
  ClassHierarchy hierarchy = new ClassHierarchy(component);
  CoreTypes coreTypes = new CoreTypes(component);
  new KernelSubtypeTest(coreTypes, hierarchy, environment).run();
}

class KernelSubtypeTest extends SubtypeTest<DartType, KernelEnvironment> {
  final CoreTypes coreTypes;

  final ClassHierarchy hierarchy;

  final KernelEnvironment environment;

  KernelSubtypeTest(this.coreTypes, this.hierarchy, this.environment);

  @override
  bool get skipFutureOrPromotion => true;

  DartType toType(String text, KernelEnvironment environment) {
    return environment.kernelFromParsedType(type_parser.parse(text).single);
  }

  bool isSubtypeImpl(DartType subtype, DartType supertype) {
    return new TypeEnvironment(coreTypes, hierarchy).isSubtypeOf(
        subtype, supertype, SubtypeCheckMode.ignoringNullabilities);
  }

  KernelEnvironment extend(String typeParameters) {
    if (typeParameters?.isEmpty ?? true) return environment;
    return const KernelFromParsedType()
        .computeTypeParameterEnvironment(
            type_parser.parseTypeVariables("<$typeParameters>"), environment)
        .environment;
  }
}
