// Copyright (c) 2017, 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.

/// Indexed entity interfaces for modeling elements derived from Kernel IR.

import '../elements/entities.dart';

abstract class _Indexed {
  late final int _index;
}

abstract class IndexedLibrary extends _Indexed implements LibraryEntity {
  /// Library index used for fast lookup in [KernelToElementMapBase].
  int get libraryIndex => _index;
}

abstract class IndexedClass extends _Indexed implements ClassEntity {
  /// Class index used for fast lookup in [KernelToElementMapBase].
  int get classIndex => _index;
}

abstract class IndexedMember extends _Indexed implements MemberEntity {
  /// Member index used for fast lookup in [KernelToElementMapBase].
  int get memberIndex => _index;
}

abstract class IndexedFunction extends _Indexed
    implements IndexedMember, FunctionEntity {}

abstract class IndexedConstructor
    implements IndexedFunction, ConstructorEntity {}

abstract class IndexedField implements IndexedMember, FieldEntity {}

abstract class IndexedTypeVariable extends _Indexed
    implements TypeVariableEntity {
  /// Type variable index used for fast lookup in [KernelToElementMapBase].
  int get typeVariableIndex => _index;
}

abstract class IndexedLocal extends _Indexed implements Local {
  int get localIndex => _index;
}

/// Base implementation for an index based map of entities of type [E].
abstract class EntityMapBase<E extends _Indexed> {
  bool _closed = false;

  int _size = 0;
  final List<E?> _list = <E?>[];

  /// Returns the [index]th entity in the map.
  E? getEntity(int index) => _list[index];

  /// Returns the number of non-null entities in the map.
  int get size => _size;

  /// Returns the number (null and non-null) entities in the map.
  int get length => _list.length;

  /// Closes the entity map, prohibiting further registration.
  ///
  /// This is used to ensure that no new entities are added while serializing
  /// modular code generation data.
  void close() {
    _closed = true;
  }
}

/// Index based map of entities of type [E].
class EntityMap<E extends _Indexed> extends EntityMapBase<E> {
  /// Registers a new [entity].
  ///
  /// The index of [entity] is set to match its index in the entity list in this
  /// map.
  E0 register<E0 extends E>(E0 entity) {
    assert(
        !_closed, "Trying to register $entity @ ${_list.length} when closed.");
    entity._index = _list.length;
    _list.add(entity);
    _size++;
    return entity;
  }

  /// Registers a new [entity] by the given [index].
  E0 registerByIndex<E0 extends E>(int index, E0 entity) {
    assert(index >= _list.length);
    _list.length = index;
    return register(entity);
  }

  /// Calls [f] for each non-null entity.
  void forEach<E0 extends E>(void f(E0 entity)) {
    for (int index = 0; index < _list.length; index++) {
      final entity = _list[index] as E0?;
      if (entity != null) {
        f(entity);
      }
    }
  }
}

/// Base implementation of an index based map of entities of type [E] with a
/// corresponding data object of type [D].
abstract class EntityDataMapBase<E extends _Indexed, D>
    extends EntityMapBase<E> {
  final List<D?> _data = <D?>[];

  /// Returns the data object stored for the [index]th entity.
  D getData(E entity) {
    int index = entity._index;
    if (index < _list.length && index >= _data.length) {
      throw StateError(
          'Data is in the process of being created for ${_list[index]}.');
    }
    return _data[index]!;
  }
}

/// Index based map of entities of type [E] with a corresponding data object
/// of type [D].
class EntityDataMap<E extends _Indexed, D> extends EntityDataMapBase<E, D> {
  /// Mark entity [index] as missing
  void skipIndex(int index) {
    assert(index == _list.length);
    _list.add(null);
    _data.add(null);
  }

  /// Registers a new [entity] with an associated [data] object.
  ///
  /// The index of [entity] is set to match its index in the entity and data
  /// lists in this map.
  E0 register<E0 extends E, D0 extends D>(E0 entity, D0 data,
      {bool setEntityIndex = true}) {
    assert(
        !_closed, "Trying to register $entity @ ${_list.length} when closed.");
    assert(
        _list.length == _data.length,
        'Data list length ${_data.length} inconsistent '
        'with entity list length ${_list.length}.');
    if (setEntityIndex) {
      entity._index = _list.length;
    } else {
      assert(entity._index == _list.length,
          'Trying to register entity with in incorrect order. ');
    }
    _list.add(entity);
    _size++;
    assert(data != null);
    _data.add(data);
    return entity;
  }

  /// Registers a new [entity] with an associated [data] object by the given
  /// [index].
  E0 registerByIndex<E0 extends E, D0 extends D>(
      int index, E0 entity, D0 data) {
    assert(index >= _list.length);
    _list.length = _data.length = index;
    return register(entity, data);
  }

  /// Calls [f] for each non-null entity with its corresponding data object.
  void forEach<E0 extends E, D0 extends D>(void f(E0 entity, D0 data)) {
    if (_list.length != _data.length) {
      throw StateError('Data is in the process of being created.');
    }
    for (int index = 0; index < _list.length; index++) {
      final entity = _list[index] as E0?;
      if (entity != null) {
        f(entity, _data[index] as D0);
      }
    }
  }
}

/// Base implementation for an index based of entities of type [E] with a
/// corresponding data object of type [D] and an environment of type [V].
abstract class EntityDataEnvMapBase<E extends _Indexed, D, V>
    extends EntityDataMapBase<E, D> {
  final List<V> _env = <V>[];

  /// Returns the environment object stored for the [index]th entity.
  V getEnv(E entity) {
    int index = entity._index;
    if (index < _list.length && index >= _env.length) {
      throw StateError(
          'Env is in the process of being created for ${_list[index]}.');
    }
    return _env[index];
  }
}

/// Index based of entities of type [E] with a corresponding data object of
/// type [D] and an environment of type [V].
class EntityDataEnvMap<E extends _Indexed, D, V>
    extends EntityDataEnvMapBase<E, D, V> {
  /// Registers a new [entity] with an associated [data] object and environment
  /// [env].
  ///
  /// The index of [entity] is set to match its index in the entity, data and
  /// environment lists in this map.
  E0 register<E0 extends E, D0 extends D, V0 extends V>(
      E0 entity, D0 data, V0 env,
      {bool setEntityIndex = true}) {
    assert(
        !_closed, "Trying to register $entity @ ${_list.length} when closed.");
    assert(
        _list.length == _data.length,
        'Data list length ${_data.length} inconsistent '
        'with entity list length ${_list.length}.');
    assert(
        _list.length == _env.length,
        'Env list length ${_env.length} inconsistent '
        'with entity list length ${_list.length}.');
    if (setEntityIndex) {
      entity._index = _list.length;
    } else {
      assert(entity._index == _list.length,
          'Trying to register entity with in incorrect order. ');
    }
    _list.add(entity);
    _size++;
    assert(data != null);
    _data.add(data);
    assert(env != null);
    _env.add(env);
    return entity;
  }

  /// Registers a new [entity] with an associated [data] object and environment
  /// [env] by the given [index].
  E0 registerByIndex<E0 extends E, D0 extends D, V0 extends V>(
      int index, E0 entity, D0 data, V0 env) {
    assert(index >= _list.length);
    _list.length = _data.length = _env.length = index;
    return register(entity, data, env);
  }

  void _preRegister<E0 extends E, V0 extends V>(E0 entity, V0 env) {
    assert(
        !_closed, "Trying to register $entity @ ${_list.length} when closed.");
    assert(
        _list.length == _env.length,
        'Env list length ${_env.length} inconsistent '
        'with entity list length ${_list.length}.');
    entity._index = _list.length;
    _list.add(entity);
    _size++;
    assert(env != null);
    _env.add(env);
  }

  /// Registers a new [entity] with an associated environment [env] by the given
  /// [index]. [postRegisterData] should be called with the same [entity] after
  /// this is called and before any other entity is registered.
  void preRegisterByIndex<E0 extends E, V0 extends V>(
      int index, E0 entity, V0 env) {
    assert(index >= _list.length);
    _list.length = _data.length = _env.length = index;
    _preRegister(entity, env);
  }

  /// Registers an [entity] with an associated [data] object. This should only
  /// be used if the entity was pre-registered with [preRegisterByIndex].
  void postRegisterData<E0 extends E, D0 extends D>(E0 entity, D0 data) {
    assert(
        !_closed, "Trying to register $entity @ ${_list.length} when closed.");
    assert(
        (_list.length - 1) == _data.length,
        'Data list length ${_data.length} inconsistent '
        'with entity list length ${_list.length}.');
    assert(data != null);
    _data.add(data);
  }

  /// Calls [f] for each non-null entity with its corresponding data object and
  /// environment.
  void forEach<E0 extends E, D0 extends D, V0 extends V>(
      void f(E0 entity, D0 data, V0 env)) {
    if (_list.length != _data.length) {
      throw StateError('Data is in the process of being created.');
    }
    if (_list.length != _env.length) {
      throw StateError('Env is in the process of being created.');
    }
    for (int index = 0; index < _list.length; index++) {
      final entity = _list[index] as E0?;
      if (entity != null) {
        f(entity, _data[index] as D0, _env[index] as V0);
      }
    }
  }
}
