// Copyright (c) 2022, 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:collection';

import 'package:compiler/src/serialization/serialization.dart';

/// Interface for data that may be deserialized lazily.
///
/// This interface should be used to wrap data objects that aren't needed in
/// later phases of the compiler. Usage of this class should follow a set
/// pattern. Given a class `C` with a field `m0` of type `E` that we wish to
/// make deferrable:
///
/// 1) `m0` should be replaced with an internal field, `_m1`, of type
///  `Deferrable<E>`.
/// 2) An internal constructor should be added to `C` that takes a `d` of type
///  `Deferrable<E>` to initialize `_m1`. This internal constructor should be
///  called from the readFromSource method/factory to create the instance
///  of `C`. `d` should be obtained using [DataSourceReader.readDeferrable].
/// 3) Any existing constructors of `C` should maintain the same signature
///  and initialize `_m1` passing `m` to [Deferrable.eager] where m is the value
///  previously used to initialize `m0`.
/// 4) If there are external references to `m0` then `C`s interface should be
///  maintained. A getter `m0` should be added: `E get m0 => _m1.loaded()`
/// 5) If all references to `m0` were internal, they can simply be replaced
///  with calls to `_m1.loaded()`.
///
/// Example class before:
///
/// class Foo {
///   final Bar bar;
///
///   Foo(this.bar);
///
///   factory Foo.readFromSource(DataSourceReader reader) {
///     return Foo(Bar.readFromSource(reader));
///   }
/// }
///
/// After:
///
/// class Foo {
///   Bar get bar => _bar.loaded();
///   final Deferrable<Bar> _bar;
///
///   Foo(Bar bar) : _bar = Deferrable.eager(bar);
///   Foo._deserialized(this._bar);
///
///   factory Foo.readFromSource(DataSourceReader reader) {
///     return Foo._deserialized(
///         reader.readDeferrable(() => Bar.readFromSource(reader)));
///   }
/// }
abstract class Deferrable<E> {
  E loaded();

  factory Deferrable.deferred(DataSourceReader reader, E f(), int offset,
          {bool cacheData = true}) =>
      cacheData
          ? _DeferredCache(reader, f, offset)
          : _Deferred(reader, f, offset);
  const factory Deferrable.eager(E data) = _Eager;

  const Deferrable();
}

class _Eager<E> extends Deferrable<E> {
  final E _data;
  @override
  E loaded() => _data;
  const _Eager(this._data);
}

class _Deferred<E> extends Deferrable<E> {
  final DataSourceReader _reader;
  final E Function() _dataLoader;
  final int _dataOffset;
  @override
  E loaded() => _reader.readWithOffset(_dataOffset, _dataLoader);
  _Deferred(this._reader, this._dataLoader, this._dataOffset);
}

class _DeferredCache<E> extends Deferrable<E> {
  final int _dataOffset;
  // Below fields are nullable so they can be cleared after loading.
  DataSourceReader? _reader;
  E Function()? _dataLoader;
  late final E _data = _loadData();

  @override
  E loaded() => _data;

  E _loadData() {
    final reader = _reader!;
    final dataLoader = _dataLoader!;
    _reader = null;
    _dataLoader = null;
    return reader.readWithOffset(_dataOffset, dataLoader);
  }

  _DeferredCache(this._reader, this._dataLoader, this._dataOffset);
}

/// Implementation of [Map] in which each value of type [V] is internally
/// [Deferrable].
///
/// This map should be used when values of type [V] are expensive to
/// deserialize. This abstracts away the laziness allowing the deferred map to
/// be used as if the values were not deferred.
///
/// The provided map can have a mix of eager and lazy [Deferrable]s if
/// there are a mix of expensive and cheap values.
class DeferrableValueMap<K, V> with MapMixin<K, V> {
  DeferrableValueMap(this._map);
  final Map<K, Deferrable<V>> _map;
  @override
  V? operator [](Object? key) {
    return _map[key]?.loaded();
  }

  @override
  void operator []=(K key, V value) {
    _map[key] = Deferrable.eager(value);
  }

  @override
  void clear() {
    _map.clear();
  }

  @override
  Iterable<K> get keys => _map.keys;

  @override
  V? remove(Object? key) {
    return _map.remove(key)?.loaded();
  }

  @override
  V putIfAbsent(K key, V ifAbsent()) {
    return _map.putIfAbsent(key, () => Deferrable.eager(ifAbsent())).loaded();
  }
}
