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

import 'remote_instance.dart';

/// All serialization must be done in a serialization Zone, which tells it
/// whether we are the client or server.
///
/// In [SerializationMode.server], sets up a remote instance cache to use when
/// deserializing remote instances back to their original instance.
T withSerializationMode<T>(
  SerializationMode mode,
  T Function() fn, {
  Serializer Function()? serializerFactory,
  Deserializer Function(Object? data)? deserializerFactory,
}) =>
    runZoned(fn, zoneValues: {
      #serializationMode: mode,
      if (!mode.isClient) remoteInstanceZoneKey: <int, RemoteInstance>{}
    });

/// Serializable interface
abstract class Serializable {
  /// Serializes this object using [serializer].
  void serialize(Serializer serializer);
}

/// A push based object serialization interface.
abstract class Serializer {
  /// Serializes a [String].
  void addString(String value);

  /// Serializes a nullable [String].
  void addNullableString(String? value) =>
      value == null ? addNull() : addString(value);

  /// Serializes a [double].
  void addDouble(double value);

  /// Serializes a nullable [double].
  void addNullableDouble(double? value) =>
      value == null ? addNull() : addDouble(value);

  /// Serializes an [int].
  void addInt(int value);

  /// Serializes a nullable [int].
  void addNullableInt(int? value) => value == null ? addNull() : addInt(value);

  /// Serializes a [bool].
  void addBool(bool value);

  /// Serializes a nullable [bool].
  void addNullableBool(bool? value) =>
      value == null ? addNull() : addBool(value);

  /// Serializes a `null` literal.
  void addNull();

  /// Used to signal the start of an arbitrary length list of items.
  void startList();

  /// Used to signal the end of an arbitrary length list of items.
  void endList();

  /// Returns the resulting serialized object.
  Object get result;
}

/// A pull based object deserialization interface.
///
/// You must call [moveNext] before reading any items, and in order to advance
/// to the next item.
abstract class Deserializer {
  /// Checks if the current value is a null, returns `true` if so and `false`
  /// otherwise.
  bool checkNull();

  /// Reads the current value as a non-nullable [String].
  bool expectBool();

  /// Reads the current value as a nullable [bool].
  bool? expectNullableBool() => checkNull() ? null : expectBool();

  /// Reads the current value as a non-nullable [double].
  double expectDouble();

  /// Reads the current value as a nullable [double].
  double? expectNullableDouble() => checkNull() ? null : expectDouble();

  /// Reads the current value as a non-nullable [int].
  int expectInt();

  /// Reads the current value as a nullable [int].
  int? expectNullableInt() => checkNull() ? null : expectInt();

  /// Reads the current value as a non-nullable [String].
  String expectString();

  /// Reads the current value as a nullable [String].
  String? expectNullableString() => checkNull() ? null : expectString();

  /// Asserts that the current item is the start of a list.
  ///
  /// An example for how to read from a list is as follows:
  ///
  /// var json = JsonReader.fromString(source);
  /// I know it's a list of strings.
  ///
  /// ```
  ///   var result = <String>[];
  ///   deserializer.moveNext();
  ///   deserializer.expectList();
  ///   while (json.moveNext()) {
  ///     result.add(json.expectString());
  ///   }
  ///   // Can now read later items, but need to call `moveNext` again to move
  ///   // past the list.
  ///   deserializer.moveNext();
  ///   deserializer.expectBool();
  /// ```
  void expectList();

  /// Moves to the next item, returns `false` if there are no more items to
  /// read.
  ///
  /// If inside of a list, this returns `false` when the end of the list is
  /// reached, and moves back to the parent, but does not advance it, so another
  /// call to `moveNext` is needed. See example in the [expectList] docs.
  bool moveNext();
}

class JsonSerializer implements Serializer {
  /// The full result.
  final _result = <Object?>[];

  /// A path to the current list we are modifying.
  late List<List<Object?>> _path = [_result];

  /// Returns the result as an unmodifiable [Iterable].
  ///
  /// Asserts that all [List] entries have not been closed with [endList].
  @override
  Iterable<Object?> get result {
    assert(_path.length == 1);
    return _result;
  }

  @override
  void addBool(bool value) => _path.last.add(value);
  @override
  void addNullableBool(bool? value) => _path.last.add(value);

  @override
  void addDouble(double value) => _path.last.add(value);
  @override
  void addNullableDouble(double? value) => _path.last.add(value);

  @override
  void addInt(int value) => _path.last.add(value);
  @override
  void addNullableInt(int? value) => _path.last.add(value);

  @override
  void addString(String value) => _path.last.add(value);
  @override
  void addNullableString(String? value) => _path.last.add(value);

  @override
  void addNull() => _path.last.add(null);

  @override
  void startList() {
    List<Object?> sublist = [];
    _path.last.add(sublist);
    _path.add(sublist);
  }

  @override
  void endList() {
    _path.removeLast();
  }
}

class JsonDeserializer implements Deserializer {
  /// The root source list to read from.
  final Iterable<Object?> _source;

  /// The path to the current iterator we are reading from.
  late List<Iterator<Object?>> _path = [];

  /// Whether we have received our first [moveNext] call.
  bool _initialized = false;

  /// Initialize this deserializer from `_source`.
  JsonDeserializer(this._source);

  @override
  bool checkNull() => _expectValue<Object?>() == null;

  @override
  void expectList() => _path.add(_expectValue<Iterable<Object?>>().iterator);

  @override
  bool expectBool() => _expectValue();
  @override
  bool? expectNullableBool() => _expectValue();

  @override
  double expectDouble() => _expectValue();
  @override
  double? expectNullableDouble() => _expectValue();

  @override
  int expectInt() => _expectValue();
  @override
  int? expectNullableInt() => _expectValue();

  @override
  String expectString() => _expectValue();
  @override
  String? expectNullableString() => _expectValue();

  /// Reads the current value and casts it to [T].
  T _expectValue<T>() {
    if (!_initialized) {
      throw new StateError(
          'You must call `moveNext()` before reading any values.');
    }
    return _path.last.current as T;
  }

  @override
  bool moveNext() {
    if (!_initialized) {
      _path.add(_source.iterator);
      _initialized = true;
    }

    // Move the current iterable, if its at the end of its items remove it from
    // the current path and return false.
    if (!_path.last.moveNext()) {
      _path.removeLast();
      return false;
    }

    return true;
  }
}

class ByteDataSerializer extends Serializer {
  final BytesBuilder _builder = new BytesBuilder();

  // Re-usable 8 byte list and view for encoding doubles.
  final Uint8List _eightByteList = new Uint8List(8);
  late final ByteData _eightByteListData =
      new ByteData.sublistView(_eightByteList);

  @override
  void addBool(bool value) => _builder
      .addByte(value ? DataKind.boolTrue.index : DataKind.boolFalse.index);

  @override
  void addDouble(double value) {
    _eightByteListData.setFloat64(0, value);
    _builder
      ..addByte(DataKind.float64.index)
      ..add(_eightByteList);
  }

  @override
  void addNull() => _builder.addByte(DataKind.nil.index);

  @override
  void addInt(int value) {
    if (value >= 0x0) {
      if (value + DataKind.values.length <= 0xff) {
        _builder..addByte(value + DataKind.values.length);
      } else if (value <= 0xff) {
        _builder
          ..addByte(DataKind.uint8.index)
          ..addByte(value);
      } else if (value <= 0xffff) {
        _builder
          ..addByte(DataKind.uint16.index)
          ..addByte(value >> 8)
          ..addByte(value);
      } else if (value <= 0xffffffff) {
        _builder
          ..addByte(DataKind.uint32.index)
          ..addByte(value >> 24)
          ..addByte(value >> 16)
          ..addByte(value >> 8)
          ..addByte(value);
      } else {
        _builder
          ..addByte(DataKind.uint64.index)
          ..addByte(value >> 56)
          ..addByte(value >> 48)
          ..addByte(value >> 40)
          ..addByte(value >> 32)
          ..addByte(value >> 24)
          ..addByte(value >> 16)
          ..addByte(value >> 8)
          ..addByte(value);
      }
    } else {
      if (value >= -0x80) {
        _builder
          ..addByte(DataKind.int8.index)
          ..addByte(value);
      } else if (value >= -0x8000) {
        _builder
          ..addByte(DataKind.int16.index)
          ..addByte(value >> 8)
          ..addByte(value);
      } else if (value >= -0x8000000) {
        _builder
          ..addByte(DataKind.int32.index)
          ..addByte(value >> 24)
          ..addByte(value >> 16)
          ..addByte(value >> 8)
          ..addByte(value);
      } else {
        _builder
          ..addByte(DataKind.int64.index)
          ..addByte(value >> 56)
          ..addByte(value >> 48)
          ..addByte(value >> 40)
          ..addByte(value >> 32)
          ..addByte(value >> 24)
          ..addByte(value >> 16)
          ..addByte(value >> 8)
          ..addByte(value);
      }
    }
  }

  @override
  void addString(String value) {
    for (int i = 0; i < value.length; i++) {
      if (value.codeUnitAt(i) > 0xff) {
        _addTwoByteString(value);
        return;
      }
    }
    _addOneByteString(value);
  }

  void _addOneByteString(String value) {
    _builder.addByte(DataKind.oneByteString.index);
    addInt(value.length);
    for (int i = 0; i < value.length; i++) {
      _builder.addByte(value.codeUnitAt(i));
    }
  }

  void _addTwoByteString(String value) {
    _builder.addByte(DataKind.twoByteString.index);
    addInt(value.length);
    for (int i = 0; i < value.length; i++) {
      int codeUnit = value.codeUnitAt(i);
      switch (Endian.host) {
        case Endian.little:
          _builder
            ..addByte(codeUnit)
            ..addByte(codeUnit >> 8);
          break;
        case Endian.big:
          _builder
            ..addByte(codeUnit >> 8)
            ..addByte(codeUnit);
          break;
      }
    }
  }

  @override
  void endList() => _builder.addByte(DataKind.endList.index);

  @override
  void startList() => _builder.addByte(DataKind.startList.index);

  @override
  Uint8List get result => _builder.takeBytes();
}

class ByteDataDeserializer extends Deserializer {
  final ByteData _bytes;
  int _byteOffset = 0;
  int? _byteOffsetIncrement = 0;

  ByteDataDeserializer(this._bytes);

  /// Reads the next [DataKind] and advances [_byteOffset].
  DataKind _readKind([int offset = 0]) {
    int value = _bytes.getUint8(_byteOffset + offset);
    if (value < DataKind.values.length) {
      return DataKind.values[value];
    } else {
      return DataKind.directEncodedUint8;
    }
  }

  @override
  bool checkNull() {
    _byteOffsetIncrement = 1;
    return _readKind() == DataKind.nil;
  }

  @override
  bool expectBool() {
    DataKind kind = _readKind();
    _byteOffsetIncrement = 1;
    if (kind == DataKind.boolTrue) {
      return true;
    } else if (kind == DataKind.boolFalse) {
      return false;
    } else {
      throw new StateError('Expected a bool but found a $kind');
    }
  }

  @override
  double expectDouble() {
    DataKind kind = _readKind();
    if (kind != DataKind.float64) {
      throw new StateError('Expected a double but found a $kind');
    }
    _byteOffsetIncrement = 9;
    return _bytes.getFloat64(_byteOffset + 1);
  }

  @override
  int expectInt() => _expectInt(0);

  int _expectInt(int offset) {
    DataKind kind = _readKind(offset);
    if (kind == DataKind.directEncodedUint8) {
      _byteOffsetIncrement = offset + 1;
      return _bytes.getUint8(_byteOffset + offset) - DataKind.values.length;
    }
    offset += 1;
    int result;
    switch (kind) {
      case DataKind.int8:
        result = _bytes.getInt8(_byteOffset + offset);
        _byteOffsetIncrement = 1 + offset;
        break;
      case DataKind.int16:
        result = _bytes.getInt16(_byteOffset + offset);
        _byteOffsetIncrement = 2 + offset;
        break;
      case DataKind.int32:
        result = _bytes.getInt32(_byteOffset + offset);
        _byteOffsetIncrement = 4 + offset;
        break;
      case DataKind.int64:
        result = _bytes.getInt64(_byteOffset + offset);
        _byteOffsetIncrement = 8 + offset;
        break;
      case DataKind.uint8:
        result = _bytes.getUint8(_byteOffset + offset);
        _byteOffsetIncrement = 1 + offset;
        break;
      case DataKind.uint16:
        result = _bytes.getUint16(_byteOffset + offset);
        _byteOffsetIncrement = 2 + offset;
        break;
      case DataKind.uint32:
        result = _bytes.getUint32(_byteOffset + offset);
        _byteOffsetIncrement = 4 + offset;
        break;
      case DataKind.uint64:
        result = _bytes.getUint64(_byteOffset + offset);
        _byteOffsetIncrement = 8 + offset;
        break;
      default:
        throw new StateError('Expected an int but found a $kind');
    }
    return result;
  }

  @override
  void expectList() {
    DataKind kind = _readKind();
    if (kind != DataKind.startList) {
      throw new StateError('Expected the start to a list but found a $kind');
    }
    _byteOffsetIncrement = 1;
  }

  @override
  String expectString() {
    DataKind kind = _readKind();
    int length = _expectInt(1);
    int offset = _byteOffsetIncrement! + _byteOffset;
    if (kind == DataKind.oneByteString) {
      _byteOffsetIncrement = _byteOffsetIncrement! + length;
      return new String.fromCharCodes(
          _bytes.buffer.asUint8List(offset, length));
    } else if (kind == DataKind.twoByteString) {
      length = length * 2;
      _byteOffsetIncrement = _byteOffsetIncrement! + length;
      Uint8List bytes =
          new Uint8List.fromList(_bytes.buffer.asUint8List(offset, length));
      return new String.fromCharCodes(bytes.buffer.asUint16List());
    } else {
      throw new StateError('Expected a string but found a $kind');
    }
  }

  @override
  bool moveNext() {
    int? increment = _byteOffsetIncrement;
    _byteOffsetIncrement = null;
    if (increment == null) {
      throw new StateError("Can't move until consuming the current element");
    }
    _byteOffset += increment;
    if (_byteOffset >= _bytes.lengthInBytes) {
      return false;
    } else if (_readKind() == DataKind.endList) {
      // You don't explicitly consume list end markers.
      _byteOffsetIncrement = 1;
      return false;
    } else {
      return true;
    }
  }
}

enum DataKind {
  nil,
  boolTrue,
  boolFalse,
  directEncodedUint8, // Encoded in the kind byte.
  startList,
  endList,
  int8,
  int16,
  int32,
  int64,
  uint8,
  uint16,
  uint32,
  uint64,
  float64,
  oneByteString,
  twoByteString,
}

/// Must be set using `withSerializationMode` before doing any serialization or
/// deserialization.
SerializationMode get serializationMode {
  SerializationMode? mode =
      Zone.current[#serializationMode] as SerializationMode?;
  if (mode == null) {
    throw new StateError('No SerializationMode set, you must do all '
        'serialization inside a call to `withSerializationMode`.');
  }
  return mode;
}

/// Returns the current deserializer factory for the zone.
Deserializer Function(Object?) get deserializerFactory {
  switch (serializationMode) {
    case SerializationMode.byteDataClient:
    case SerializationMode.byteDataServer:
      return (Object? message) => new ByteDataDeserializer(
          new ByteData.sublistView(message as Uint8List));
    case SerializationMode.jsonClient:
    case SerializationMode.jsonServer:
      return (Object? message) =>
          new JsonDeserializer(message as Iterable<Object?>);
  }
}

/// Returns the current serializer factory for the zone.
Serializer Function() get serializerFactory {
  switch (serializationMode) {
    case SerializationMode.byteDataClient:
    case SerializationMode.byteDataServer:
      return () => new ByteDataSerializer();
    case SerializationMode.jsonClient:
    case SerializationMode.jsonServer:
      return () => new JsonSerializer();
  }
}

/// Some objects are serialized differently on the client side versus the server
/// side. This indicates the different modes, as well as the format used.
enum SerializationMode {
  byteDataClient,
  byteDataServer,
  jsonServer,
  jsonClient,
}

extension SerializationModeHelpers on SerializationMode {
  bool get isClient {
    switch (this) {
      case SerializationMode.byteDataClient:
      case SerializationMode.jsonClient:
        return true;
      case SerializationMode.byteDataServer:
      case SerializationMode.jsonServer:
        return false;
    }
  }

  /// A stable string to write in code.
  String get asCode {
    switch (this) {
      case SerializationMode.byteDataClient:
        return 'SerializationMode.byteDataClient';
      case SerializationMode.byteDataServer:
        return 'SerializationMode.byteDataServer';
      case SerializationMode.jsonClient:
        return 'SerializationMode.jsonClient';
      case SerializationMode.jsonServer:
        return 'SerializationMode.jsonServer';
    }
  }
}
