// 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:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/dart/analysis/dependency/library_builder.dart';
import 'package:analyzer/src/dart/analysis/dependency/node.dart';
import 'package:test/test.dart';

import '../../resolution/context_collection_resolution.dart';

class BaseDependencyTest extends PubPackageResolutionTest {
  late final String a;
  late final String b;
  late final String c;
  late final Uri aUri;
  late final Uri bUri;
  late final Uri cUri;

  bool hasDartCore = false;

  void assertNodes(List<Node> actualNodes, List<ExpectedNode> expectedNodes,
      {Node? expectedEnclosingClass}) {
    expect(actualNodes, hasLength(expectedNodes.length));
    for (var expectedNode in expectedNodes) {
      var topNode = _getNode(
        actualNodes,
        uri: expectedNode.uri,
        name: expectedNode.name,
        kind: expectedNode.kind,
      );
      expect(topNode.enclosingClass, expectedEnclosingClass);

      if (expectedNode.classMembers != null) {
        assertNodes(topNode.classMembers!, expectedNode.classMembers!,
            expectedEnclosingClass: topNode);
      } else {
        expect(topNode.classMembers, isNull);
      }

      if (expectedNode.classTypeParameters != null) {
        assertNodes(
          topNode.classTypeParameters!,
          expectedNode.classTypeParameters!,
          expectedEnclosingClass: topNode,
        );
      } else {
        expect(topNode.classTypeParameters, isNull);
      }
    }
  }

  Future<Library> buildTestLibrary(String path, String content) async {
//    if (!hasDartCore) {
//      hasDartCore = true;
//      await _addLibraryByUri('dart:core');
//      await _addLibraryByUri('dart:async');
//      await _addLibraryByUri('dart:math');
//      await _addLibraryByUri('dart:_internal');
//    }

    newFile(path, content: content);

    var analysisDriver = driverFor(path);
    analysisDriver.changeFile(path);
    await analysisDriver.applyPendingFileChanges();

    var units = await _resolveLibrary(path);
    var uri = units.first.declaredElement!.source.uri;

    return buildLibrary(uri, units);

//    tracker.addLibrary(uri, units);
//
//    var library = tracker.libraries[uri];
//    expect(library, isNotNull);
//
//    return library;
  }

  Node getNode(Library library,
      {required String name,
      NodeKind? kind,
      String? memberOf,
      String? typeParameterOf}) {
    var uri = library.uri;
    var nodes = library.declaredNodes;
    if (memberOf != null) {
      var class_ = _getNode(nodes, uri: uri, name: memberOf);
      expect(
        class_.kind,
        anyOf(NodeKind.CLASS, NodeKind.ENUM, NodeKind.MIXIN),
      );
      nodes = class_.classMembers!;
    } else if (typeParameterOf != null) {
      var class_ = _getNode(nodes, uri: uri, name: typeParameterOf);
      expect(class_.kind, anyOf(NodeKind.CLASS, NodeKind.MIXIN));
      nodes = class_.classTypeParameters!;
    }
    return _getNode(nodes, uri: uri, name: name, kind: kind);
  }

  @override
  void setUp() {
    super.setUp();
//    var logger = PerformanceLog(null);
//    tracker = DependencyTracker(logger);
    a = convertPath('$testPackageLibPath/a.dart');
    b = convertPath('$testPackageLibPath/b.dart');
    c = convertPath('$testPackageLibPath/c.dart');
    aUri = Uri.parse('package:test/a.dart');
    bUri = Uri.parse('package:test/b.dart');
    cUri = Uri.parse('package:test/c.dart');
  }

//  Future _addLibraryByUri(String uri) async {
//    var path = driver.sourceFactory.forUri(uri).fullName;
//    var unitResult = await driver.getUnitElement(path);
//
//    var signature = ApiSignature();
//    signature.addString(unitResult.signature);
//    var signatureBytes = signature.toByteList();
//
//    tracker.addLibraryElement(unitResult.element.library, signatureBytes);
//  }

  Node _getNode(List<Node> nodes,
      {required Uri uri, required String name, NodeKind? kind}) {
    var nameObj = LibraryQualifiedName(uri, name);
    for (var node in nodes) {
      if (node.name == nameObj) {
        if (kind != null && node.kind != kind) {
          fail('Expected $kind "$name", found ${node.kind}');
        }
        return node;
      }
    }
    fail('Expected to find $uri::$name in:\n    ${nodes.join('\n    ')}');
  }

  Future<List<CompilationUnit>> _resolveLibrary(String libraryPath) async {
    var session = contextFor(libraryPath).currentSession;
    var resolvedLibrary = await session.getResolvedLibrary(libraryPath);
    resolvedLibrary as ResolvedLibraryResult;
    return resolvedLibrary.units.map((ru) => ru.unit).toList();
  }
}

class ExpectedNode {
  final Uri uri;
  final String name;
  final NodeKind kind;
  final List<ExpectedNode>? classMembers;
  final List<ExpectedNode>? classTypeParameters;

  ExpectedNode(
    this.uri,
    this.name,
    this.kind, {
    this.classMembers,
    this.classTypeParameters,
  });
}
