// Copyright (c) 2017, 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 'dart:io' show File, IOSink;
import 'dart:typed_data' show BytesBuilder, Uint8List;

import 'package:_fe_analyzer_shared/src/parser/formal_parameter_kind.dart';
import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' show Token;
import 'package:_fe_analyzer_shared/src/scanner/token.dart'
    show SyntheticToken, TokenType;
import 'package:front_end/src/base/lookup_result.dart';
import 'package:front_end/src/base/scope.dart';
import 'package:kernel/ast.dart';
import 'package:kernel/binary/ast_to_binary.dart';
import 'package:kernel/clone.dart';
import 'package:kernel/text/ast_to_text.dart';

import '../base/combinator.dart';
import '../base/configuration.dart';
import '../base/identifiers.dart';
import '../base/modifiers.dart';
import '../builder/declaration_builders.dart';
import '../builder/fixed_type_builder.dart';
import '../builder/formal_parameter_builder.dart';
import '../builder/library_builder.dart';
import '../builder/metadata_builder.dart';
import '../builder/omitted_type_builder.dart';
import '../builder/record_type_builder.dart';
import '../builder/type_builder.dart';
import '../fragment/fragment.dart';
import '../source/fragment_factory.dart';
import '../source/source_type_parameter_builder.dart';
import 'body_builder.dart';

/// The name for the synthesized field used to store information of
/// unserializable exports in a [Library].
///
/// For instance, if a [Library] tries to export two declarations with the same
/// name, the unserializable exports will map this name to the corresponding
/// error message.
const String unserializableExportName = '_exports#';

/// Sentinel value used in unserializable exports to signal an export of
/// 'dynamic' from 'dart:core'.
const String exportDynamicSentinel = '<dynamic>';

/// Sentinel value used in unserializable exports to signal an export of
/// 'Never' from 'dart:core'.
const String exportNeverSentinel = '<Never>';

// Coverage-ignore(suite): Not run.
void printNodeOn(Node? node, StringSink sink, {NameSystem? syntheticNames}) {
  if (node == null) {
    sink.write("null");
  } else {
    syntheticNames ??= new NameSystem();
    new Printer(sink, syntheticNames: syntheticNames).writeNode(node);
  }
}

// Coverage-ignore(suite): Not run.
void printQualifiedNameOn(Member? member, StringSink sink) {
  if (member == null) {
    sink.write("null");
  } else {
    sink.write(member.enclosingLibrary.importUri);
    sink.write("::");
    Class? cls = member.enclosingClass;
    if (cls != null) {
      sink.write(cls.name);
      sink.write("::");
    }
    sink.write(member.name.text);
  }
}

void bindCoreType(
  LibraryBuilder coreLibrary,
  NamedTypeBuilder typeBuilder, {
  bool isNullClass = false,
}) {
  TypeDeclarationBuilder typeDeclarationBuilder =
      coreLibrary.lookupRequiredLocalMember(typeBuilder.typeName.name)
          as TypeDeclarationBuilder;
  typeBuilder.bind(coreLibrary, typeDeclarationBuilder);
  if (isNullClass) {
    (typeDeclarationBuilder as ClassBuilder).isNullClass = true;
  }
}

// Coverage-ignore(suite): Not run.
/// Print the given [component].  Do nothing if it is `null`.  If the
/// [libraryFilter] is provided, then only libraries that satisfy it are
/// printed.
void printComponentText(
  Component? component, {
  bool Function(Library library)? libraryFilter,
  bool showOffsets = false,
}) {
  if (component == null) return;
  StringBuffer sb = new StringBuffer();
  Printer printer = new Printer(sb, showOffsets: showOffsets);
  printer.writeComponentProblems(component);
  for (Library library in component.libraries) {
    if (libraryFilter != null && !libraryFilter(library)) continue;
    printer.writeLibraryFile(library);
  }
  printer.writeConstantTable(component);
  print(sb);
}

// Coverage-ignore(suite): Not run.
/// Write [component] to file only including libraries that match [filter].
Future<Null> writeComponentToFile(
  Component component,
  Uri uri, {
  bool Function(Library library)? filter,
}) async {
  File output = new File.fromUri(uri);
  IOSink sink = output.openWrite();
  try {
    BinaryPrinter printer = new BinaryPrinter(sink, libraryFilter: filter);
    printer.writeComponentFile(component);
  } finally {
    await sink.close();
  }
}

// Coverage-ignore(suite): Not run.
/// Serialize the libraries in [component] that match [filter].
Uint8List serializeComponent(
  Component component, {
  bool Function(Library library)? filter,
  bool includeSources = true,
  bool includeOffsets = true,
}) {
  ByteSink byteSink = new ByteSink();
  BinaryPrinter printer = new BinaryPrinter(
    byteSink,
    libraryFilter: filter,
    includeSources: includeSources,
    includeOffsets: includeOffsets,
  );
  printer.writeComponentFile(component);
  return byteSink.builder.takeBytes();
}

const String kDebugClassName = "#DebugClass";

// Coverage-ignore(suite): Not run.
class _CollectLibraryDependencies extends RecursiveVisitor {
  Set<LibraryDependency> foundLibraryDependencies = {};

  @override
  void visitLoadLibrary(LoadLibrary node) {
    foundLibraryDependencies.add(node.import);
  }

  @override
  void visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) {
    foundLibraryDependencies.add(node.import);
  }
}

// Coverage-ignore(suite): Not run.
Component createExpressionEvaluationComponent(Procedure procedure) {
  Library realLibrary = procedure.enclosingLibrary;

  Uri uri = new Uri(scheme: 'evaluate', path: 'source');
  Library fakeLibrary = new Library(uri, fileUri: uri)
    ..setLanguageVersion(realLibrary.languageVersion);

  // Add deferred library dependencies. They are needed for serializing
  // references to deferred libraries. We can just claim ownership of the ones
  // we find as they were created when doing the expression compilation.
  _CollectLibraryDependencies collectLibraryDependencies =
      new _CollectLibraryDependencies();
  procedure.accept(collectLibraryDependencies);
  for (LibraryDependency libraryDependency
      in collectLibraryDependencies.foundLibraryDependencies) {
    fakeLibrary.addDependency(libraryDependency);
  }

  TreeNode? realClass = procedure.parent;
  if (realClass is Class) {
    Class fakeClass = new Class(name: kDebugClassName, fileUri: uri)
      ..parent = fakeLibrary;
    Map<TypeParameter, TypeParameter> typeParams =
        <TypeParameter, TypeParameter>{};
    Map<TypeParameter, DartType> typeSubstitution = <TypeParameter, DartType>{};
    for (TypeParameter typeParam in realClass.typeParameters) {
      TypeParameter newNode = new TypeParameter(typeParam.name)
        ..declaration = fakeClass;
      typeParams[typeParam] = newNode;
      typeSubstitution[typeParam] = new TypeParameterType(
        newNode,
        typeParam.computeNullabilityFromBound(),
      );
    }
    CloneVisitorWithMembers cloner = new CloneVisitorWithMembers(
      typeSubstitution: typeSubstitution,
      typeParams: typeParams,
    );

    for (TypeParameter typeParam in realClass.typeParameters) {
      fakeClass.typeParameters.add(
        typeParam.accept<TreeNode>(cloner) as TypeParameter,
      );
    }

    if (realClass.supertype != null) {
      // supertype is null for Object.
      fakeClass.supertype = new Supertype.byReference(
        realClass.supertype!.className,
        realClass.supertype!.typeArguments.map(cloner.visitType).toList(),
      );
    }

    // Rebind the type parameters in the procedure.
    procedure = cloner.cloneProcedure(procedure, null);
    procedure.parent = fakeClass;
    fakeClass.procedures.add(procedure);
    fakeLibrary.classes.add(fakeClass);
  } else {
    fakeLibrary.procedures.add(procedure);
    procedure.parent = fakeLibrary;
  }

  // TODO(vegorov) find a way to preserve metadata.
  Component component = new Component(libraries: [fakeLibrary]);
  component.setMainMethodAndMode(null, false);
  return component;
}

// Coverage-ignore(suite): Not run.
List<int> serializeProcedure(Procedure procedure) {
  return serializeComponent(createExpressionEvaluationComponent(procedure));
}

/// A [Sink] that directly writes data into a byte builder.
class ByteSink implements Sink<List<int>> {
  final BytesBuilder builder = new BytesBuilder();

  @override
  void add(List<int> data) {
    builder.add(data);
  }

  @override
  // Coverage-ignore(suite): Not run.
  void close() {}
}

int compareProcedures(Procedure a, Procedure b) {
  int i = "${a.fileUri}".compareTo("${b.fileUri}");
  if (i != 0) return i;
  return a.fileOffset.compareTo(b.fileOffset);
}

List<Combinator>? toCombinators(List<CombinatorBuilder>? combinatorBuilders) {
  if (combinatorBuilders == null) {
    // Note: it's safe to return null here as Kernel's LibraryDependency will
    // convert null to an empty list.
    return null;
  }

  return new List<Combinator>.generate(combinatorBuilders.length, (int i) {
    CombinatorBuilder combinator = combinatorBuilders[i];
    List<String> nameList = combinator.names.toList();
    return combinator.isShow
        ? new Combinator.show(nameList)
        : new Combinator.hide(nameList);
  }, growable: true);
}

final Token dummyToken = new SyntheticToken(TokenType.AT, -1);
final Identifier dummyIdentifier = new SimpleIdentifier(dummyToken);
final CombinatorBuilder dummyCombinator = new CombinatorBuilder(
  false,
  {},
  -1,
  dummyUri,
);
final MetadataBuilder dummyMetadataBuilder = new MetadataBuilder(
  dummyToken,
  dummyUri,
);
final TypeBuilder dummyTypeBuilder = new FixedTypeBuilderImpl(
  dummyDartType,
  dummyUri,
  -1,
);
final FormalParameterBuilder dummyFormalParameterBuilder =
    new FormalParameterBuilder(
      FormalParameterKind.requiredPositional,
      Modifiers.empty,
      const ImplicitTypeBuilder(),
      '',
      -1,
      fileUri: dummyUri,
      hasImmediatelyDeclaredInitializer: false,
    );
final FunctionTypeParameterBuilder dummyFunctionTypeParameterBuilder =
    new FunctionTypeParameterBuilder(
      FormalParameterKind.requiredPositional,
      const ImplicitTypeBuilder(),
      '',
    );
final NominalParameterBuilder dummyNominalVariableBuilder =
    new SourceNominalParameterBuilder(
      new DirectNominalParameterDeclaration(
        name: NominalParameterBuilder.noNameSentinel,
        kind: TypeParameterKind.function,
        isWildcard: false,
        fileOffset: -1,
        fileUri: dummyUri,
      ),
    );
final TypeParameterFragment dummyTypeParameterFragment =
    new TypeParameterFragment(
      metadata: null,
      name: '',
      nameOffset: -1,
      fileUri: dummyUri,
      kind: TypeParameterKind.function,
      isWildcard: false,
      variableName: '',
      typeParameterScope: dummyLookupScope,
    );
final SourceStructuralParameterBuilder dummyStructuralVariableBuilder =
    new SourceStructuralParameterBuilder(
      new RegularStructuralParameterDeclaration(
        metadata: null,
        name: StructuralParameterBuilder.noNameSentinel,
        fileOffset: -1,
        fileUri: dummyUri,
        isWildcard: false,
      ),
    );
final Label dummyLabel = new Label('', -1);
final RecordTypeFieldBuilder dummyRecordTypeFieldBuilder =
    new RecordTypeFieldBuilder(null, dummyTypeBuilder, null, -1);
final FieldInfo dummyFieldInfo = new FieldInfo(
  dummyIdentifier,
  null,
  dummyToken,
  -1,
);
final Configuration dummyConfiguration = new Configuration(-1, '', '', '');
final LookupScope dummyLookupScope = new _DummyLookupScope();

// Coverage-ignore(suite): Not run.
class _DummyLookupScope implements LookupScope {
  @override
  void forEachExtension(void Function(ExtensionBuilder p1) f) {}

  @override
  ScopeKind get kind => ScopeKind.library;

  @override
  LookupResult? lookup(String name) => null;
}
