// Copyright (c) 2021, 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:kernel/binary/ast_from_binary.dart';
import 'package:kernel/src/tool/find_referenced_libraries.dart';
import 'utils.dart';

main() {
  Library lib;
  {
    /// Create a library with two classes (A and B) where class A - in its
    /// constructor - invokes the constructor for B.
    final Uri uri = Uri.parse('org-dartlang:///lib.dart');
    lib = new Library(uri, fileUri: uri);
    final Class classA = new Class(name: "A", fileUri: uri);
    lib.addClass(classA);
    final Class classB = new Class(name: "B", fileUri: uri);
    lib.addClass(classB);

    final Constructor classBConstructor = new Constructor(
        new FunctionNode(new EmptyStatement()),
        name: new Name(""),
        fileUri: uri);
    classB.addConstructor(classBConstructor);

    final Constructor classAConstructor = new Constructor(
        new FunctionNode(new ExpressionStatement(new ConstructorInvocation(
            classBConstructor, new Arguments.empty()))),
        name: new Name(""),
        fileUri: uri);
    classA.addConstructor(classAConstructor);
  }
  Component c = new Component(libraries: [lib]);
  c.setMainMethodAndMode(null, false, NonNullableByDefaultCompiledMode.Weak);
  List<int> loadMe = serializeComponent(c);

  // Load and make sure we can get at class B from class A (i.e. that it's
  // loaded correctly!).
  Component loadedComponent = new Component();
  new BinaryBuilder(loadMe,
          disableLazyReading: false, disableLazyClassReading: false)
      .readSingleFileComponent(loadedComponent);
  {
    final Library loadedLib = loadedComponent.libraries.single;
    final Class loadedClassA = loadedLib.classes.first;
    final ExpressionStatement loadedConstructorA =
        loadedClassA.constructors.single.function.body as ExpressionStatement;
    final ConstructorInvocation loadedConstructorInvocation =
        loadedConstructorA.expression as ConstructorInvocation;
    final Class pointedToClass =
        loadedConstructorInvocation.target.enclosingClass;
    final Library pointedToLib =
        loadedConstructorInvocation.target.enclosingLibrary;

    Set<Library> reachable = findAllReferencedLibraries([loadedLib]);
    if (reachable.length != 1 || reachable.single != loadedLib) {
      throw "Expected only the single library to be reachable, "
          "but found $reachable";
    }

    final Class loadedClassB = loadedLib.classes[1];
    if (loadedClassB != pointedToClass) {
      throw "Doesn't point to the right class";
    }
    if (pointedToLib != loadedLib) {
      throw "Doesn't point to the right library";
    }
  }
  // Attempt to load again, overwriting the old stuff. This should logically
  // "relink" to the newly loaded version.
  Component loadedComponent2 = new Component(nameRoot: loadedComponent.root);
  new BinaryBuilder(loadMe,
          disableLazyReading: false,
          disableLazyClassReading: false,
          alwaysCreateNewNamedNodes: true)
      .readSingleFileComponent(loadedComponent2);
  {
    final Library loadedLib = loadedComponent2.libraries.single;
    final Class loadedClassA = loadedLib.classes.first;
    final ExpressionStatement loadedConstructorA =
        loadedClassA.constructors.single.function.body as ExpressionStatement;
    final ConstructorInvocation loadedConstructorInvocation =
        loadedConstructorA.expression as ConstructorInvocation;
    final Class pointedToClass =
        loadedConstructorInvocation.target.enclosingClass;
    final Library pointedToLib =
        loadedConstructorInvocation.target.enclosingLibrary;

    Set<Library> reachable = findAllReferencedLibraries([loadedLib]);
    if (reachable.length != 1 || reachable.single != loadedLib) {
      throw "Expected only the single library to be reachable, "
          "but found $reachable";
    }

    final Class loadedClassB = loadedLib.classes[1];
    if (loadedClassB != pointedToClass) {
      throw "Doesn't point to the right class";
    }
    if (pointedToLib != loadedLib) {
      throw "Doesn't point to the right library";
    }
  }
}
