// 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:convert';
import 'dart:typed_data';

import 'package:kernel/ast.dart';

import 'dynamic_module_kernel_metadata.dart';
import 'reference_extensions.dart';

class _EntityToIdMapper {
  final Component component;
  final Map<TreeNode, int> _ids;

  _EntityToIdMapper(this.component)
      : _ids =
            (component.metadata[DynamicModuleGlobalIdRepository.repositoryTag]
                    as DynamicModuleGlobalIdRepository)
                .mapping;

  int idForClass(Class cls) {
    return _ids[cls]!;
  }

  int idForMember(Member member) {
    return _ids[member]!;
  }

  (int, int) idForReference(Reference reference) {
    return (idForMember(reference.asMember), _flagForReference(reference));
  }

  static int _flagForReference(Reference reference) {
    if (reference.isImplicitGetter) return 0;
    if (reference.isImplicitSetter) return 1;
    if (reference.isTearOffReference) return 2;
    if (reference.isConstructorBodyReference) return 3;
    if (reference.isInitializerReference) return 4;
    if (reference.isTypeCheckerReference) return 5;
    if (reference.isCheckedEntryReference) return 6;
    if (reference.isUncheckedEntryReference) return 7;
    if (reference.isBodyReference) return 8;
    assert(reference == reference.asMember.reference);
    return 9;
  }
}

class _IdToEntityMapper {
  final Component component;
  final Map<int, TreeNode> _mapping;

  static Map<int, TreeNode> _makeIdsMap(Component component) {
    final mapping =
        (component.metadata[DynamicModuleGlobalIdRepository.repositoryTag]
                as DynamicModuleGlobalIdRepository)
            .mapping;
    final inverse = <int, TreeNode>{};
    mapping.forEach((node, id) {
      inverse[id] = node;
    });
    return inverse;
  }

  _IdToEntityMapper(this.component) : _mapping = _makeIdsMap(component);

  Class classForId(int id) {
    return _mapping[id] as Class;
  }

  Member memberForId(int id) {
    return _mapping[id] as Member;
  }

  Reference referenceForId(int memberId, int flag) {
    final member = _mapping[memberId] as Member;
    return _referenceForFlag(member, flag);
  }

  static Reference _referenceForFlag(Member member, int flag) {
    if (flag == 0) return (member as Field).getterReference;
    if (flag == 1) return (member as Field).setterReference!;
    if (flag == 2) return (member as Procedure).tearOffReference;
    if (flag == 3) return (member as Constructor).constructorBodyReference;
    if (flag == 4) return (member as Constructor).initializerReference;
    if (flag == 5) return member.typeCheckerReference;
    if (flag == 6) return member.checkedEntryReference;
    if (flag == 7) return member.uncheckedEntryReference;
    if (flag == 8) return member.bodyReference;
    assert(flag == 9);
    return member.reference;
  }
}

class DataSerializer {
  final _BinaryDataSink _sink = _BinaryDataSink();
  final _EntityToIdMapper _mapper;
  final Map<String, int> _stringIndexer = {};

  DataSerializer(Component component) : _mapper = _EntityToIdMapper(component);

  void writeNullable<T>(T? value, void Function(T value) write) {
    if (value != null) {
      _sink.writeBool(true);
      write(value);
    } else {
      _sink.writeBool(false);
    }
  }

  void writeString(String value) {
    int? index = _stringIndexer[value];
    if (index == null) {
      index = _stringIndexer[value] = _stringIndexer.length;
      _sink.writeInt(index);
      _sink.writeString(value);
    } else {
      _sink.writeInt(index);
    }
  }

  void writeInt(int value) {
    _sink.writeInt(value);
  }

  void writeBool(bool value) {
    _sink.writeByte(value ? 1 : 0);
  }

  void writeBoolList(List<bool> values) {
    _sink.writeInt(values.length);
    int index = 0;
    for (final value in values) {
      index = (index << 1) | (value ? 1 : 0);
    }
    _sink.writeInt(index);
  }

  void writeEnum<E extends Enum>(E value) {
    writeInt(value.index);
  }

  void writeClass(Class cls) {
    writeInt(_mapper.idForClass(cls));
  }

  void writeMember(Member member) {
    final memberId = _mapper.idForMember(member);
    writeInt(memberId);
  }

  void writeReference(Reference reference) {
    final (memberId, referenceFlag) = _mapper.idForReference(reference);
    writeInt(memberId);
    writeInt(referenceFlag);
  }

  void writeMap<K, V>(Map<K, V> map, void Function(K key) writeKey,
      void Function(V value) writeValue) {
    writeInt(map.length);
    map.forEach((key, value) {
      writeKey(key);
      writeValue(value);
    });
  }

  void writeList<E>(Iterable<E> list, void Function(E value) writeValue) {
    writeInt(list.length);
    for (final value in list) {
      writeValue(value);
    }
  }

  Uint8List takeBytes() {
    return _sink.takeBytes();
  }
}

class DataDeserializer {
  final _BinaryDataSource _source;
  final _IdToEntityMapper _mapper;
  final List<String> _stringIndexer = [];

  DataDeserializer(Uint8List bytes, Component component)
      : _source = _BinaryDataSource(bytes),
        _mapper = _IdToEntityMapper(component);

  T? readNullable<T>(T Function() read) {
    return _source.readBool() ? read() : null;
  }

  String readString() {
    final index = _source.readInt();
    if (index < _stringIndexer.length) return _stringIndexer[index];
    final value = _source.readString();
    assert(index == _stringIndexer.length);
    _stringIndexer.add(value);
    return value;
  }

  int readInt() {
    return _source.readInt();
  }

  bool readBool() {
    return _source.readInt() == 1;
  }

  List<bool> readBoolList() {
    final length = _source.readInt();
    final values = _source.readInt();
    return List.generate(length, (i) => (values >> (length - i - 1)) & 1 == 1);
  }

  E readEnum<E extends Enum>(List<E> values) {
    int index = _source.readInt();
    assert(
        0 <= index && index < values.length,
        "Invalid data kind index. "
        "Expected one of $values, found index $index.");
    return values[index];
  }

  Class readClass() {
    return _mapper.classForId(_source.readInt());
  }

  Member readMember() {
    return _mapper.memberForId(_source.readInt());
  }

  Reference readReference() {
    final memberId = _source.readInt();
    final flag = _source.readInt();
    return _mapper.referenceForId(memberId, flag);
  }

  Map<K, V> readMap<K, V>(K Function() readKey, V Function() readValue) {
    final length = _source.readInt();
    final map = <K, V>{};
    for (int i = 0; i < length; i++) {
      final key = readKey();
      final value = readValue();
      map[key] = value;
    }
    return map;
  }

  List<E> readList<E>(E Function() readValue) {
    final length = _source.readInt();
    final list = <E>[];
    for (int i = 0; i < length; i++) {
      list.add(readValue());
    }
    return list;
  }
}

class _BinaryDataSink {
  static const int _initSinkSize = 50 * 1024;

  Uint8List _data = Uint8List(_initSinkSize);
  int _length = 0;

  _BinaryDataSink();

  int get length => _length;

  void _ensure(int size) {
    // Ensure space for at least `size` additional bytes.
    if (_data.length < _length + size) {
      int newLength = _data.length * 2;
      while (newLength < _length + size) {
        newLength *= 2;
      }
      _data = Uint8List(newLength)..setRange(0, _data.length, _data);
    }
  }

  void writeByte(int byte) {
    assert(byte == byte & 0xFF);
    _ensure(1);
    _data[_length++] = byte;
  }

  void writeBytes(Uint8List bytes) {
    _ensure(bytes.length);
    _data.setRange(_length, _length += bytes.length, bytes);
  }

  void writeString(String value) {
    final bytes = utf8.encode(value);
    writeInt(bytes.length);
    writeBytes(bytes);
  }

  void writeBool(bool value) {
    writeByte(value ? 1 : 0);
  }

  void writeInt(int value) {
    assert(value >= 0 && value >> 30 == 0);
    if (value < 0x80) {
      writeByte(value);
    } else if (value < 0x4000) {
      writeByte((value >> 8) | 0x80);
      writeByte(value & 0xFF);
    } else {
      writeByte((value >> 24) | 0xC0);
      writeByte((value >> 16) & 0xFF);
      writeByte((value >> 8) & 0xFF);
      writeByte(value & 0xFF);
    }
  }

  Uint8List takeBytes() {
    final result = Uint8List.sublistView(_data, 0, _length);
    // Free the reference to the large data list so it can potentially be
    // tree-shaken.
    _data = Uint8List(0);
    return result;
  }
}

class _BinaryDataSource {
  int _byteOffset = 0;
  final Uint8List _bytes;

  _BinaryDataSource(this._bytes);

  void begin(String tag) {}

  void end(String tag) {}

  int _readByte() => _bytes[_byteOffset++];

  String readString() {
    int length = readInt();
    return utf8.decode(
        Uint8List.sublistView(_bytes, _byteOffset, _byteOffset += length));
  }

  bool readBool() {
    return _readByte() != 0;
  }

  int readInt() {
    var byte = _readByte();
    if (byte & 0x80 == 0) {
      // 0xxxxxxx
      return byte;
    } else if (byte & 0x40 == 0) {
      // 10xxxxxx
      return ((byte & 0x3F) << 8) | _readByte();
    } else {
      // 11xxxxxx
      return ((byte & 0x3F) << 24) |
          (_readByte() << 16) |
          (_readByte() << 8) |
          _readByte();
    }
  }

  int get length => _bytes.length;
  int get currentOffset => _byteOffset;
}
