// Copyright (c) 2018, 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 'serialization.dart';

abstract class IndexedSource<E extends Object> {
  Map<int, E> get cache;

  E? read(DataSourceReader source, E Function() readValue);
  E? readWithoutCache(DataSourceReader source, E Function() readValue);
}

abstract class IndexedSink<E extends Object> {
  Map<E, int> get cache;

  void write(DataSinkWriter sink, E? value, void Function(E value) writeValue);
}

const int _dataInPlaceIndicator = 0;
const int _nullIndicator = 1;
const int _nonCompactOffsetIndicator = 2;
const int _indicatorOffset = 3;

/// Facilitates indexed reads and writes for [IndexedSource] and [IndexedSink].
///
/// Created and stores shared [IndexedSource] and [IndexedSink] instances for
/// cached types. Copies indices from sources to sinks when a sink is requested
/// so that the indices are shared across data files.
///
/// [DataSourceReader] instances must be registered so that contiguous start
/// offsets can be set on each reader. This allows global offsets to be
/// correctly calculated by the indices. See [UnorderedIndexedSource] for more
/// info.
class SerializationIndices {
  final Map<Type, IndexedSource> _indexedSources = {};
  final Map<Type, IndexedSink> _indexedSinks = {};
  final List<DataSourceReader> _sources = [];
  final bool testMode;

  SerializationIndices({this.testMode = false});

  int registerSource(DataSourceReader source) {
    int startOffset;
    if (_sources.isEmpty) {
      startOffset = 0;
    } else {
      final lastSource = _sources.last;
      startOffset = lastSource.startOffset + lastSource.length;
    }
    _sources.add(source);
    return startOffset;
  }

  IndexedSource<E> getIndexedSource<E extends Object>() {
    final source =
        (_indexedSources[E] ??= UnorderedIndexedSource<E>(this))
            as IndexedSource<E>;
    if (testMode) {
      /// In test mode we ensure that the values we read out are identical to
      /// the values we write in. When copying the elements we turn the local
      /// offsets to global offsets so that the source cache will hit.
      /// Note: Mapped sinks will not get copied over since the mapped write
      /// type will be different from the read type.
      final sink = _indexedSinks[E] as IndexedSink<E>?;
      sink?.cache.forEach((value, offset) {
        // We convert local offsets to relative offsets because source caching
        // uses the relative address space. We want to ensure objects that are
        // serialized and immediately deserialized during testing share the same
        // cached references.
        source.cache[_localToGlobalForTesting(offset)] = value;
      });
    }
    return source;
  }

  IndexedSink<E> getIndexedSink<E extends Object>({bool identity = false}) {
    return _getIndexedSink<E, E>(null, identity: identity);
  }

  IndexedSink<T> getMappedIndexedSink<E extends Object, T extends Object>(
    T Function(E value) f,
  ) {
    return _getIndexedSink<E, T>(f, identity: false);
  }

  IndexedSink<T> _getIndexedSink<E extends Object, T extends Object>(
    T Function(E value)? f, {
    required bool identity,
  }) {
    final sink =
        (_indexedSinks[T] ??= UnorderedIndexedSink<T>(identity: identity))
            as IndexedSink<T>;
    final source = _indexedSources[E] as UnorderedIndexedSource<E>?;
    source?.cache.forEach((offset, value) {
      final key = (f != null ? f(value) : value) as T;
      sink.cache[key] = offset;
    });
    return sink;
  }
}

/// We use one bit to represent that an offset is local to the same data file.
const int _numLocalityBits = 1;

/// We can only compactly represent offsets up to the max supported by the
/// [BinaryDataSink] minus the number of bits used to represent offset locality.
const int _maxCompactOffset = BinaryDataSink.maxIntValue >> _numLocalityBits;

// Real offsets are the offsets into the file the data is written in.
// Local offsets are real offsets with an extra indicator bit set to 1.
// Global offsets are offsets into the address space of all files with an
// extra indicator bit set to 0.
int _realToLocalOffset(int offset) => (offset << 1) | 1;
int _realToGlobalOffset(int offset, DataSourceReader source) =>
    (offset + source.startOffset) << 1;
bool _isLocalOffset(int offset) => (offset & 1) == 1;
int _offsetWithoutIndicator(int offset) => offset >> 1;
int _globalToRealOffset(int offset, DataSourceReader source) =>
    (offset >> 1) - source.startOffset;
int _localToGlobalOffset(int offset, DataSourceReader source) =>
    _realToGlobalOffset(offset >> 1, source);
int _localToGlobalForTesting(int offset) => offset & ~1;

/// Data sink helper that canonicalizes [E?] values using IDs.
///
/// Writes a unique ID in place of previously visited indexable values. This
/// ID is the offset in the data stream at which the serialized value can be
/// read. The read and write order do not need to be the same because no matter
/// what occurrence of the ID we encounter, we can always recover the value.
///
/// We increment all written offsets by an adjustment value in order to
/// distinguish which source file the offset is from on deserialization.
/// See [UnorderedIndexedSource] for more info.
class UnorderedIndexedSink<E extends Object> implements IndexedSink<E> {
  final Map<E, int> _cache;

  UnorderedIndexedSink({bool identity = false})
    : _cache = identity ? Map.identity() : {};

  @override
  Map<E, int> get cache => _cache;

  /// Write a reference to [value] to the data sink.
  ///
  /// If [value] has not been canonicalized yet, [writeValue] is called to
  /// serialize the [value] itself.
  @override
  void write(DataSinkWriter sink, E? value, void Function(E value) writeValue) {
    if (value == null) {
      // We reserve 1 as an indicator for `null`.
      sink.writeInt(_nullIndicator);
      return;
    }
    final offset = _cache[value];
    if (offset == null) {
      // We reserve 0 as an indicator that the data is written 'here'.
      sink.writeInt(_dataInPlaceIndicator);
      _cache[value] = _realToLocalOffset(sink.length);
      writeValue(value);
    } else {
      final writtenOffset = offset + _indicatorOffset;
      if (writtenOffset >= _maxCompactOffset) {
        sink.writeInt(_nonCompactOffsetIndicator);
        sink.writeUint32(offset);
      } else {
        sink.writeInt(writtenOffset);
      }
    }
  }
}

/// Data source helper reads canonicalized [E?] values through IDs.
///
/// Reads indexable elements via their unique ID. Each ID is the offset in
/// the data stream at which the serialized value can be read. The first time an
/// ID is discovered we jump to the value's offset, deserialize it, and
/// then jump back to the 'current' offset.
///
/// In order to read cached offsets across files, we map offset ranges to a
/// specific source:
///
///   offset 0  .. K1    --- source S1
///   offset K1 .. K2    --- source S2
///   offset K2 .. K3    --- source S3
///
/// This effectively treats all the files as a contiguous address space with
/// offsets being global to the start of the first source.
///
/// Offsets are written in one of two forms. Either as a local offset, an offset
/// relative to the start of the same file, or as a global offset, an offset
/// relative to the start of the concatenated address space of all sources. The
/// two forms are indicated via the lowest bit, the former has that bit set,
/// the latter does not. Local offsets are turned into global offsets when they
/// are written into a later file.
///
/// If an offset is encountered outside the block accessible to current source,
/// [SerializationIndices] provides pointers to the previous sources to check
/// (i.e. previous blocks in the address space).
class UnorderedIndexedSource<E extends Object> implements IndexedSource<E> {
  final Map<int, E> _cache = {};
  final SerializationIndices _indices;

  UnorderedIndexedSource(this._indices);

  @override
  Map<int, E> get cache => _cache;

  /// Reads a reference to an [E?] value from the data source or the backing
  /// cache if the index has already been read.
  ///
  /// If the value hasn't yet been read, [readValue] is called to deserialize
  /// the value itself.
  @override
  E? read(DataSourceReader source, E Function() readValue) {
    final markerOrOffset = source.readInt();

    if (markerOrOffset == _dataInPlaceIndicator) {
      final globalOffset = _realToGlobalOffset(source.currentOffset, source);
      // We have to read the value regardless of whether or not it's cached to
      // move the reader past it.
      final value = readValue();
      final cachedValue = _cache[globalOffset];
      if (cachedValue != null) return cachedValue;
      _cache[globalOffset] = value;
      return value;
    } else if (markerOrOffset == _nullIndicator) {
      return null;
    } else {
      int offset;
      if (markerOrOffset == _nonCompactOffsetIndicator) {
        offset = source.readUint32();
      } else {
        offset = markerOrOffset - _indicatorOffset;
      }
      bool isLocal = _isLocalOffset(offset);
      final globalOffset = isLocal
          ? _localToGlobalOffset(offset, source)
          : offset;
      final cachedValue = _cache[globalOffset];
      if (cachedValue != null) return cachedValue;
      return _readAtOffset(
        source,
        readValue,
        globalOffset,
        isLocal,
        isCached: true,
      );
    }
  }

  /// Reads a reference to an [E?] value from the data source.
  ///
  /// Does not cache the read value so each call to [readWithoutCache] of the
  /// associated index will create a new object.
  @override
  E? readWithoutCache(DataSourceReader source, E Function() readValue) {
    final markerOrOffset = source.readInt();

    if (markerOrOffset == _dataInPlaceIndicator) {
      return readValue();
    } else if (markerOrOffset == _nullIndicator) {
      return null;
    } else {
      int offset;
      if (markerOrOffset == _nonCompactOffsetIndicator) {
        offset = source.readUint32();
      } else {
        offset = markerOrOffset - _indicatorOffset;
      }
      bool isLocal = _isLocalOffset(offset);
      final globalOffset = isLocal
          ? _localToGlobalOffset(offset, source)
          : offset;
      return _readAtOffset(
        source,
        readValue,
        globalOffset,
        isLocal,
        isCached: false,
      );
    }
  }

  DataSourceReader findSource(int globalOffset) {
    final offset = _offsetWithoutIndicator(globalOffset);
    final sources = _indices._sources;
    for (int i = sources.length - 1; i >= 0; i--) {
      final source = sources[i];
      if (source.startOffset <= offset) return source;
    }
    throw StateError('Could not find source for $offset.');
  }

  E _readAtOffset(
    DataSourceReader source,
    E Function() readValue,
    int globalOffset,
    bool isLocal, {
    required bool isCached,
  }) {
    final realSource = isLocal ? source : findSource(globalOffset);
    final realOffset = _globalToRealOffset(globalOffset, realSource);
    final value = isLocal
        ? source.readWithOffset(realOffset, readValue)
        : source.readWithSource(
            realSource,
            () => source.readWithOffset(realOffset, readValue),
          );
    if (isCached) _cache[globalOffset] = value;
    return value;
  }
}
