// 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:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart' as ast;
import 'package:analyzer/src/dart/ast/mixin_super_invoked_names.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/resolver/scope.dart' show LibraryScope;
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/combinator.dart';
import 'package:analyzer/src/summary2/constructor_initializer_resolver.dart';
import 'package:analyzer/src/summary2/default_value_resolver.dart';
import 'package:analyzer/src/summary2/export.dart';
import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/link.dart';
import 'package:analyzer/src/summary2/linked_bundle_context.dart';
import 'package:analyzer/src/summary2/linked_unit_context.dart';
import 'package:analyzer/src/summary2/metadata_resolver.dart';
import 'package:analyzer/src/summary2/reference.dart';
import 'package:analyzer/src/summary2/reference_resolver.dart';
import 'package:analyzer/src/summary2/scope.dart';
import 'package:analyzer/src/summary2/types_builder.dart';

class SourceLibraryBuilder {
  final Linker linker;
  final Uri uri;
  final Reference reference;
  final LinkedNodeLibraryBuilder node;

  LinkedLibraryContext context;

  LibraryElementImpl element;
  LibraryScope libraryScope;

  /// Local declarations.
  final Scope localScope = Scope.top();

  /// The export scope of the library.
  final Scope exportScope = Scope.top();

  final List<Export> exporters = [];

  SourceLibraryBuilder(this.linker, this.uri, this.reference, this.node);

  void addExporters() {
    var unitContext = context.units[0];
    for (var directive in unitContext.unit_withDirectives.directives) {
      if (directive is ast.ExportDirective) {
        Uri uri;
        try {
          uri = _selectAbsoluteUri(directive);
          if (uri == null) continue;
        } on FormatException {
          continue;
        }

        var combinators = directive.combinators.map((node) {
          if (node is ast.ShowCombinator) {
            var nameList = node.shownNames.map((i) => i.name).toList();
            return Combinator.show(nameList);
          } else if (node is ast.HideCombinator) {
            var nameList = node.hiddenNames.map((i) => i.name).toList();
            return Combinator.hide(nameList);
          }
        }).toList();

        var exported = linker.builders[uri];
        var export = Export(this, exported, combinators);
        if (exported != null) {
          exported.exporters.add(export);
        } else {
          var references = linker.elementFactory.exportsOfLibrary('$uri');
          for (var reference in references) {
            export.addToExportScope(reference.name, reference);
          }
        }
      }
    }
  }

  /// Add top-level declaration of the library units to the local scope.
  void addLocalDeclarations() {
    for (var unitContext in context.units) {
      var unitRef = reference.getChild('@unit').getChild(unitContext.uriStr);
      var classRef = unitRef.getChild('@class');
      var enumRef = unitRef.getChild('@enum');
      var functionRef = unitRef.getChild('@function');
      var mixinRef = unitRef.getChild('@mixin');
      var typeAliasRef = unitRef.getChild('@typeAlias');
      var getterRef = unitRef.getChild('@getter');
      var setterRef = unitRef.getChild('@setter');
      var variableRef = unitRef.getChild('@variable');
      for (var node in unitContext.unit.declarations) {
        if (node is ast.ClassDeclaration) {
          var name = node.name.name;
          var reference = classRef.getChild(name);
          reference.node2 = node;
          localScope.declare(name, reference);
        } else if (node is ast.ClassTypeAlias) {
          var name = node.name.name;
          var reference = classRef.getChild(name);
          reference.node2 = node;
          localScope.declare(name, reference);
        } else if (node is ast.EnumDeclaration) {
          var name = node.name.name;
          var reference = enumRef.getChild(name);
          reference.node2 = node;
          localScope.declare(name, reference);
        } else if (node is ast.FunctionDeclaration) {
          var name = node.name.name;

          Reference containerRef;
          if (node.isGetter) {
            containerRef = getterRef;
          } else if (node.isSetter) {
            containerRef = setterRef;
          } else {
            containerRef = functionRef;
          }

          var reference = containerRef.getChild(name);
          reference.node2 = node;

          if (node.isSetter) {
            localScope.declare('$name=', reference);
          } else {
            localScope.declare(name, reference);
          }
        } else if (node is ast.FunctionTypeAlias) {
          var name = node.name.name;
          var reference = typeAliasRef.getChild(name);
          reference.node2 = node;

          localScope.declare(name, reference);
        } else if (node is ast.GenericTypeAlias) {
          var name = node.name.name;
          var reference = typeAliasRef.getChild(name);
          reference.node2 = node;

          localScope.declare(name, reference);
        } else if (node is ast.MixinDeclaration) {
          var name = node.name.name;
          var reference = mixinRef.getChild(name);
          reference.node2 = node;
          localScope.declare(name, reference);
        } else if (node is ast.TopLevelVariableDeclaration) {
          for (var variable in node.variables.variables) {
            var name = variable.name.name;

            var reference = variableRef.getChild(name);
            reference.node2 = node;

            var getter = getterRef.getChild(name);
            localScope.declare(name, getter);

            if (!variable.isConst && !variable.isFinal) {
              var setter = setterRef.getChild(name);
              localScope.declare('$name=', setter);
            }
          }
        } else {
          // TODO(scheglov) implement
          throw UnimplementedError('${node.runtimeType}');
        }
      }
    }
    if ('$uri' == 'dart:core') {
      localScope.declare('dynamic', reference.getChild('dynamic'));
    }
  }

  void addSyntheticConstructors() {
    for (var reference in localScope.map.values) {
      var node = reference.node;
      if (node == null) continue;
      if (node.kind != LinkedNodeKind.classDeclaration) continue;

      // Skip the class if it already has a constructor.
      if (node.classOrMixinDeclaration_members
          .any((n) => n.kind == LinkedNodeKind.constructorDeclaration)) {
        continue;
      }

      node.classOrMixinDeclaration_members.add(
        LinkedNodeBuilder.constructorDeclaration(
          constructorDeclaration_parameters:
              LinkedNodeBuilder.formalParameterList(),
          constructorDeclaration_body: LinkedNodeBuilder.emptyFunctionBody(),
        )..isSynthetic = true,
      );
    }
  }

  /// Return `true` if the export scope was modified.
  bool addToExportScope(String name, Reference reference) {
    if (name.startsWith('_')) return false;
    if (reference.isPrefix) return false;

    var existing = exportScope.map[name];
    if (existing == reference) return false;

    // Ambiguous declaration detected.
    if (existing != null) return false;

    exportScope.map[name] = reference;
    return true;
  }

  void buildElement() {
    element = linker.elementFactory.libraryOfUri('$uri');
    libraryScope = LibraryScope(element);
  }

  void buildInitialExportScope() {
    localScope.forEach((name, reference) {
      addToExportScope(name, reference);
    });
  }

  void collectMixinSuperInvokedNames() {
    for (var unitContext in context.units) {
      for (var declaration in unitContext.unit.declarations) {
        if (declaration is ast.MixinDeclaration) {
          var names = Set<String>();
          var collector = MixinSuperInvokedNamesCollector(names);
          for (var executable in declaration.members) {
            if (executable is ast.MethodDeclaration) {
              executable.body.accept(collector);
            }
          }
          var lazy = LazyMixinDeclaration.get(declaration);
          lazy.setSuperInvokedNames(names.toList());
        }
      }
    }
  }

  void resolveConstructors() {
    ConstructorInitializerResolver(linker, element).resolve();
  }

  void resolveDefaultValues() {
    DefaultValueResolver(linker, element).resolve();
  }

  void resolveMetadata() {
    for (CompilationUnitElementImpl unit in element.units) {
      var resolver = MetadataResolver(linker, element, unit);
      unit.linkedNode.accept(resolver);
    }
  }

  void resolveTypes(NodesToBuildType nodesToBuildType) {
    for (var unitContext in context.units) {
      var unitRef = reference.getChild('@unit');
      var unitReference = unitRef.getChild(unitContext.uriStr);
      var resolver = ReferenceResolver(
        linker.linkingBundleContext,
        nodesToBuildType,
        linker.elementFactory,
        element,
        unitReference,
        linker.contextFeatures.isEnabled(Feature.non_nullable),
        libraryScope,
      );
      unitContext.unit.accept(resolver);
    }
  }

  void resolveUriDirectives() {
    var unitContext = context.units[0];
    for (var directive in unitContext.unit.directives) {
      if (directive is ast.NamespaceDirective) {
        try {
          var uri = _selectAbsoluteUri(directive);
          if (uri != null) {
            LazyDirective.setSelectedUri(directive, '$uri');
          }
        } on FormatException {}
      }
    }
  }

  void storeExportScope() {
    var linkingBundleContext = linker.linkingBundleContext;
    for (var reference in exportScope.map.values) {
      var index = linkingBundleContext.indexOfReference(reference);
      node.exports.add(index);
    }
  }

  Uri _selectAbsoluteUri(ast.NamespaceDirective directive) {
    var relativeUriStr = _selectRelativeUri(
      directive.configurations,
      directive.uri.stringValue,
    );
    if (relativeUriStr == null || relativeUriStr.isEmpty) {
      return null;
    }
    var relativeUri = Uri.parse(relativeUriStr);
    return resolveRelativeUri(this.uri, relativeUri);
  }

  String _selectRelativeUri(
    List<ast.Configuration> configurations,
    String defaultUri,
  ) {
    for (var configuration in configurations) {
      var name = configuration.name.components.join('.');
      var value = configuration.value ?? 'true';
      if (linker.declaredVariables.get(name) == (value)) {
        return configuration.uri.stringValue;
      }
    }
    return defaultUri;
  }

  static void build(Linker linker, LinkInputLibrary inputLibrary) {
    var libraryUri = inputLibrary.source.uri;
    var libraryUriStr = '$libraryUri';
    var libraryReference = linker.rootReference.getChild(libraryUriStr);

    var libraryNode = LinkedNodeLibraryBuilder(
      uriStr: libraryUriStr,
    );

    var definingUnit = inputLibrary.units[0].unit;
    for (var directive in definingUnit.directives) {
      if (directive is ast.LibraryDirective) {
        var name = directive.name;
        libraryNode.name = name.components.map((id) => id.name).join('.');
        libraryNode.nameOffset = name.offset;
        libraryNode.nameLength = name.length;
        break;
      }
    }

    var builder = SourceLibraryBuilder(
      linker,
      libraryUri,
      libraryReference,
      libraryNode,
    );
    linker.builders[builder.uri] = builder;

    builder.context = linker.bundleContext.addLinkingLibrary(
      libraryUriStr,
      libraryNode,
      inputLibrary,
    );
  }
}

class UnitBuilder {
  final Uri uri;
  final LinkedUnitContext context;
  final LinkedNode node;

  UnitBuilder(this.uri, this.context, this.node);
}
