// Copyright (c) 2025, 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';
import 'dart:typed_data';

import 'package:kernel/ast.dart';
import 'package:kernel/binary/ast_from_binary.dart'
    show BinaryBuilderWithMetadata;
import 'package:kernel/core_types.dart';
import 'package:kernel/kernel.dart'
    show writeComponentToBinary, writeComponentToBytes;
import 'package:kernel/library_index.dart';
import 'package:path/path.dart' as path;
import 'package:vm/metadata/direct_call.dart' show DirectCallMetadataRepository;
import 'package:vm/metadata/inferred_type.dart'
    show
        InferredArgTypeMetadataRepository,
        InferredReturnTypeMetadataRepository,
        InferredTypeMetadataRepository;
import 'package:vm/metadata/procedure_attributes.dart'
    show ProcedureAttributesMetadataRepository;
import 'package:vm/metadata/table_selector.dart';

import 'class_info.dart';
import 'compiler_options.dart';
import 'dispatch_table.dart';
import 'dynamic_modules.dart';
import 'js/method_collector.dart' show JSMethods;
import 'serialization.dart';
import 'translator.dart';

const String dynamicMainModuleProcedureAttributeMetadataTag =
    'dynMod:procedureAttributes';
const String dynamicMainModuleSelectorMetadataTag = 'dynMod:selectors';

/// Repository for kernel global entity IDs.
///
/// Each class and member gets annotated with a unique ID that will allow us to
/// persist metadata about that entity across compilations.
class DynamicModuleGlobalIdRepository extends MetadataRepository<int> {
  static const repositoryTag = 'wasm.dynamic-modules.globalId';

  @override
  final String tag = repositoryTag;

  @override
  final Map<TreeNode, int> mapping = {};

  @override
  int readFromBinary(Node node, BinarySource source) {
    return source.readUInt30();
  }

  @override
  void writeToBinary(int globalId, Node node, BinarySink sink) {
    sink.writeUInt30(globalId);
  }
}

/// Repository for kernel constants.
class DynamicModuleConstantRepository
    extends MetadataRepository<Map<Constant, int>> {
  static const repositoryTag = 'wasm.dynamic-modules.constants';

  @override
  final String tag = repositoryTag;

  @override
  final Map<TreeNode, Map<Constant, int>> mapping = {};

  @override
  Map<Constant, int> readFromBinary(Node node, BinarySource source) {
    final length = source.readUInt30();
    final Map<Constant, int> constants = {};
    for (int i = 0; i < length; i++) {
      final constant = source.readConstantReference();
      final id = source.readUInt30();
      constants[constant] = id;
    }
    return constants;
  }

  @override
  void writeToBinary(Map<Constant, int> constants, Node node, BinarySink sink) {
    sink.writeUInt30(constants.length);
    constants.forEach((constant, id) {
      sink.writeConstantReference(constant);
      sink.writeUInt30(id);
    });
  }
}

class ClassMetadata {
  /// The class numbering ID assigned to this class.
  final int classId;

  /// The brand index attached to the wasm struct representing this class, if
  /// any.
  final int? brandIndex;

  ClassMetadata._(this.classId, this.brandIndex);

  factory ClassMetadata.deserialize(DataDeserializer source) {
    final classId = source.readInt() - 1;
    final brandIndex = source.readInt();

    return ClassMetadata._(classId, brandIndex == 0 ? null : brandIndex - 1);
  }

  void serialize(DataSerializer sink) {
    sink.writeInt(classId + 1);
    sink.writeInt(brandIndex == null ? 0 : brandIndex! + 1);
  }
}

class SelectorMetadata {
  final int id;
  final String name;
  final int callCount;
  final bool isSetter;
  final bool useMultipleEntryPoints;
  final bool isDynamicSubmoduleOverridable;
  final bool isDynamicSubmoduleCallable;
  final bool isNoSuchMethod;
  final SelectorTargets? checked;
  final SelectorTargets? unchecked;
  final SelectorTargets? normal;
  final List<Reference> references;

  SelectorMetadata(
      this.id,
      this.name,
      this.callCount,
      this.isSetter,
      this.useMultipleEntryPoints,
      this.isDynamicSubmoduleOverridable,
      this.isDynamicSubmoduleCallable,
      this.isNoSuchMethod,
      this.checked,
      this.unchecked,
      this.normal,
      this.references);

  void serialize(DataSerializer sink) {
    sink.writeInt(id);
    sink.writeString(name);
    sink.writeInt(callCount);
    sink.writeBoolList([
      isSetter,
      useMultipleEntryPoints,
      isDynamicSubmoduleOverridable,
      isDynamicSubmoduleCallable,
      isNoSuchMethod
    ]);
    sink.writeNullable(checked, (targets) => targets.serialize(sink));
    sink.writeNullable(unchecked, (targets) => targets.serialize(sink));
    sink.writeNullable(normal, (targets) => targets.serialize(sink));
    sink.writeList(references, sink.writeReference);
  }

  factory SelectorMetadata.deserialize(DataDeserializer source) {
    final id = source.readInt();
    final name = source.readString();
    final callCount = source.readInt();
    final [
      isSetter,
      useMultipleEntryPoints,
      isDynamicSubmoduleOverridable,
      isDynamicSubmoduleCallable,
      isNoSuchMethod
    ] = source.readBoolList();
    final checked =
        source.readNullable(() => SelectorTargets.deserialize(source));
    final unchecked =
        source.readNullable(() => SelectorTargets.deserialize(source));
    final normal =
        source.readNullable(() => SelectorTargets.deserialize(source));
    final references = source.readList(source.readReference);

    return SelectorMetadata(
        id,
        name,
        callCount,
        isSetter,
        useMultipleEntryPoints,
        isDynamicSubmoduleOverridable,
        isDynamicSubmoduleCallable,
        isNoSuchMethod,
        checked,
        unchecked,
        normal,
        references);
  }
}

class DispatchTableMetadata {
  final List<SelectorMetadata> selectors;
  final List<Reference?> table;

  // Ignore dynamic selectors since dynamic calls are not allowed from
  // submodules.

  DispatchTableMetadata(this.selectors, this.table);
}

/// Metadata produced by the main module.
///
/// This data will get serialized as part of the main module compilation process
/// and will be provided as an input to be deserialized by subsequent submodule
/// compilations.
class MainModuleMetadata {
  /// Class to metadata about the class.
  final Map<Class, ClassMetadata> classMetadata;

  /// Maps dynamic callable references to a unique ID that is used to generate
  /// the export name for the reference.
  final Map<Reference, int> callableReferenceIds;

  late final DispatchTable dispatchTable;

  /// Contains each invoked reference that targets an updateable function.
  final Set<Reference> invokedOverridableReferences;

  /// Maps invocation keys (either selector or builtin) to the implementation's
  /// index in the runtime table. Key includes whether the key was invoked
  /// with unchecked entry.
  final Map<int, int> keyInvocationToIndex;

  /// Classes in dfs order.
  final List<Class> dfsOrderClassIds;

  /// Saved flags from the main module to verify that settings have not changed
  /// between main module invocation and submodule invocation.
  final TranslatorOptions mainModuleTranslatorOptions;
  final Map<String, String> mainModuleEnvironment;

  MainModuleMetadata._(
      this.classMetadata,
      this.callableReferenceIds,
      this.dispatchTable,
      this.invokedOverridableReferences,
      this.keyInvocationToIndex,
      this.dfsOrderClassIds,
      this.mainModuleTranslatorOptions,
      this.mainModuleEnvironment);

  MainModuleMetadata.empty(
      this.mainModuleTranslatorOptions, this.mainModuleEnvironment)
      : classMetadata = {},
        callableReferenceIds = {},
        invokedOverridableReferences = {},
        keyInvocationToIndex = {},
        dfsOrderClassIds = [];

  void finalize(Translator translator) {
    translator.classInfo.forEach((cls, info) {
      final id =
          cls.isAnonymousMixin ? -1 : (info.classId as AbsoluteClassId).value;
      final structType = info.struct;
      final brandIndex =
          translator.typesBuilder.brandTypeAssignments[structType];
      classMetadata[cls] = ClassMetadata._(id, brandIndex);
    });

    dispatchTable = translator.dispatchTable;

    dfsOrderClassIds.addAll(translator.classIdNumbering.dfsOrder);

    // Annotate classes and procedures with indices for serialization.
    int nextId = 0;
    final idRepo = translator
        .component.metadata[DynamicModuleGlobalIdRepository.repositoryTag]!;

    void annotateMember(Member member) {
      idRepo.mapping[member] = nextId++;
    }

    for (final lib in translator.component.libraries) {
      for (final member in lib.members) {
        annotateMember(member);
      }
      for (final cls in lib.classes) {
        idRepo.mapping[cls] = nextId++;
        for (final member in cls.members) {
          annotateMember(member);
        }
      }
    }
  }

  void serialize(DataSerializer sink, Translator translator) {
    finalize(translator);

    sink.writeMap(classMetadata, sink.writeClass, (m) => m.serialize(sink));

    sink.writeMap(callableReferenceIds, sink.writeReference, sink.writeInt);

    dispatchTable.serialize(sink);

    sink.writeList(invokedOverridableReferences, sink.writeReference);

    sink.writeMap(keyInvocationToIndex, sink.writeInt, sink.writeInt);

    sink.writeList(dfsOrderClassIds, sink.writeClass);

    mainModuleTranslatorOptions.serialize(sink);
    sink.writeMap(mainModuleEnvironment, sink.writeString, sink.writeString);
  }

  static MainModuleMetadata deserialize(DataDeserializer source) {
    final classMetadata = source.readMap(
        source.readClass, () => ClassMetadata.deserialize(source));

    final callableReferenceIds =
        source.readMap(source.readReference, source.readInt);

    final dispatchTable = DispatchTable.deserialize(source);

    final invokedReferences = source.readList(source.readReference).toSet();

    final keyInvocationToIndex = source.readMap(source.readInt, source.readInt);

    final dfsOrderClasses = source.readList(source.readClass);

    final mainModuleTranslatorOptions = TranslatorOptions.deserialize(source);
    final mainModuleEnvironment =
        source.readMap(source.readString, source.readString);

    final metadata = MainModuleMetadata._(
        classMetadata,
        callableReferenceIds,
        dispatchTable,
        invokedReferences,
        keyInvocationToIndex,
        dfsOrderClasses,
        mainModuleTranslatorOptions,
        mainModuleEnvironment);

    return metadata;
  }

  static void verifyMainModuleOptions(WasmCompilerOptions options) {
    final translatorOptions = options.translatorOptions;
    if (translatorOptions.enableDeferredLoading) {
      throw StateError(
          'Cannot use enable-deferred-loading with dynamic modules.');
    }
    if (translatorOptions.enableMultiModuleStressTestMode) {
      throw StateError(
          'Cannot use multi-module-stress-test-mode with dynamic modules.');
    }
    if (translatorOptions.enableMultiModuleStressTestMode) {
      throw StateError(
          'Cannot use multi-module-stress-test-mode with dynamic modules.');
    }
  }

  void verifyDynamicSubmoduleOptions(WasmCompilerOptions options) {
    final translatorOptions = options.translatorOptions;

    Never fail(String optionName) {
      throw StateError(
          'Inconsistent flag for dynamic submodule compilation: $optionName');
    }

    // TODO(natebiggs): Disallow certain flags from being used in conjunction
    // with submodules.

    if (translatorOptions.enableAsserts !=
        mainModuleTranslatorOptions.enableAsserts) {
      fail('enable-asserts');
    }
    if (translatorOptions.importSharedMemory !=
        mainModuleTranslatorOptions.importSharedMemory) {
      fail('import-shared-memory');
    }
    if (translatorOptions.inlining != translatorOptions.inlining) {
      fail('inlining');
    }
    if (translatorOptions.jsCompatibility !=
        mainModuleTranslatorOptions.jsCompatibility) {
      fail('js-compatibility');
    }
    if (translatorOptions.omitImplicitTypeChecks !=
        mainModuleTranslatorOptions.omitImplicitTypeChecks) {
      fail('omit-implicit-checks');
    }
    if (translatorOptions.omitExplicitTypeChecks !=
        mainModuleTranslatorOptions.omitExplicitTypeChecks) {
      fail('omit-explicit-checks');
    }
    if (translatorOptions.omitBoundsChecks !=
        mainModuleTranslatorOptions.omitBoundsChecks) {
      fail('omit-bounds-checks');
    }
    if (translatorOptions.polymorphicSpecialization !=
        mainModuleTranslatorOptions.polymorphicSpecialization) {
      fail('polymorphic-specialization');
    }
    // Skip printKernel
    // Skip printWasm
    if (translatorOptions.minify != mainModuleTranslatorOptions.minify) {
      fail('minify');
    }
    if (translatorOptions.verifyTypeChecks !=
        mainModuleTranslatorOptions.verifyTypeChecks) {
      fail('verify-type-checks');
    }
    // Skip verbose
    if (translatorOptions.enableExperimentalFfi !=
        mainModuleTranslatorOptions.enableExperimentalFfi) {
      fail('enable-experimental-ffi');
    }
    if (translatorOptions.enableExperimentalWasmInterop !=
        mainModuleTranslatorOptions.enableExperimentalWasmInterop) {
      fail('enable-experimental-wasm-interop');
    }
    // Skip generate source maps
    if (translatorOptions.enableDeferredLoading !=
        mainModuleTranslatorOptions.enableDeferredLoading) {
      fail('enable-deferred-loading');
    }
    if (translatorOptions.enableMultiModuleStressTestMode !=
        mainModuleTranslatorOptions.enableMultiModuleStressTestMode) {
      fail('enable-multi-module-stress-test-mode');
    }
    if (translatorOptions.inliningLimit !=
        mainModuleTranslatorOptions.inliningLimit) {
      fail('inlining-limit');
    }
    if (translatorOptions.sharedMemoryMaxPages !=
        mainModuleTranslatorOptions.sharedMemoryMaxPages) {
      fail('shared-memory-max-pages');
    }

    if (!mapEquals(options.environment, mainModuleEnvironment)) {
      fail('environment mismatch');
    }
  }
}

String _makeOptDillPath(String path) =>
    '${path.substring(0, path.length - '.dill'.length)}.opt.dill';

Future<void> serializeMainModuleComponent(
    Component component, Uri dynamicModuleMainUri,
    {required bool optimized}) async {
  // TODO(natebiggs): Serialize as a summary and filter to only necessary
  // libraries.
  await writeComponentToBinary(
      component,
      optimized
          ? _makeOptDillPath(dynamicModuleMainUri.path)
          : dynamicModuleMainUri.path,
      includeSource: false);
}

Future<(Component, JSMethods)> generateDynamicSubmoduleComponent(
    Component component,
    CoreTypes coreTypes,
    Uri dynamicModuleMainUri,
    JSMethods jsInteropMethods) async {
  final submoduleComponentBytes = writeComponentToBytes(
      Component(libraries: component.getDynamicSubmoduleLibraries(coreTypes)));
  final optimizedMainComponentBytes =
      await File(_makeOptDillPath(dynamicModuleMainUri.path)).readAsBytes();
  final concatenatedComponentBytes = Uint8List(
      submoduleComponentBytes.length + optimizedMainComponentBytes.length);
  concatenatedComponentBytes.setAll(0, optimizedMainComponentBytes);
  concatenatedComponentBytes.setAll(
      optimizedMainComponentBytes.length, submoduleComponentBytes);
  final newComponent = Component()
    ..addMetadataRepository(DynamicModuleGlobalIdRepository())
    ..addMetadataRepository(DynamicModuleConstantRepository())
    ..addMetadataRepository(ProcedureAttributesMetadataRepository())
    ..addMetadataRepository(TableSelectorMetadataRepository())
    ..addMetadataRepository(DirectCallMetadataRepository())
    ..addMetadataRepository(InferredTypeMetadataRepository())
    ..addMetadataRepository(InferredReturnTypeMetadataRepository())
    ..addMetadataRepository(InferredArgTypeMetadataRepository());
  BinaryBuilderWithMetadata(concatenatedComponentBytes)
      .readComponent(newComponent);

  // Remap js interop methods into the new component.
  final index = LibraryIndex.all(component);
  final JSMethods newJsMethods = {};
  jsInteropMethods.forEach((method, info) {
    newJsMethods[index.getProcedure(
        method.enclosingLibrary.importUri.path,
        method.enclosingClass?.name ?? LibraryIndex.topLevel,
        method.name.text)] = info;
  });
  return (newComponent, newJsMethods);
}

Future<MainModuleMetadata> deserializeMainModuleMetadata(
    Component component, WasmCompilerOptions options) async {
  final filename = options.dynamicModuleMetadataFile ??
      Uri.parse(path.setExtension(
          options.dynamicMainModuleUri!.toFilePath(), '.dyndata'));
  final dynamicModuleMetadataBytes = await File.fromUri(filename).readAsBytes();
  final source = DataDeserializer(dynamicModuleMetadataBytes, component);
  return MainModuleMetadata.deserialize(source);
}

Future<void> serializeMainModuleMetadata(Component component,
    Translator translator, WasmCompilerOptions options) async {
  final filename = options.dynamicModuleMetadataFile ??
      Uri.parse(path.setExtension(
          options.dynamicMainModuleUri!.toFilePath(), '.dyndata'));
  final serializer = DataSerializer(component);
  translator.dynamicModuleInfo!.metadata.serialize(serializer, translator);
  await File.fromUri(filename).writeAsBytes(serializer.takeBytes());
}
