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

// Originally pulled from dart:_vmservice.

part of dds;

/// [Set]-like containers which automatically generate [String] IDs for its
/// items.
class NamedLookup<E> with IterableMixin<E> {
  final IdGenerator _generator;
  final Map<String, E> _elements = {};
  final Map<E, String> _ids = {};

  NamedLookup({String prologue = ''})
      : _generator = IdGenerator(prologue: prologue);

  void add(E e) {
    final id = _generator.newId();
    _elements[id] = e;
    _ids[e] = id;
  }

  void remove(E e) {
    final id = _ids.remove(e);
    _elements.remove(id);
    _generator.release(id);
  }

  E operator [](String id) => _elements[id];
  String keyOf(E e) => _ids[e];

  Iterator<E> get iterator => _ids.keys.iterator;
}

/// Generator for unique IDs which recycles expired ones.
class IdGenerator {
  /// Fixed initial part of the ID
  final String prologue;

  // IDs in use.
  final Set<String> _used = {};

  /// IDs to be recycled (use these before generate new ones).
  final Set<String> _free = {};

  /// Next ID to generate when no recycled IDs are available.
  int _next = 0;

  IdGenerator({this.prologue = ''});

  /// Returns a new ID (possibly recycled).
  String newId() {
    String id;
    if (_free.isEmpty) {
      id = prologue + (_next++).toString();
    } else {
      id = _free.first;
    }
    _free.remove(id);
    _used.add(id);
    return id;
  }

  /// Releases the ID and mark it for recycling.
  void release(String id) {
    if (_used.remove(id)) {
      _free.add(id);
    }
  }
}
