// 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.

import 'specs/directive.dart';
import 'specs/reference.dart';

/// Collects references and automatically allocates prefixes and imports.
///
/// `Allocator` takes out the manual work of deciding whether a symbol will
/// clash with other imports in your generated code, or what imports are needed
/// to resolve all symbols in your generated code.
abstract class Allocator {
  /// An allocator that does not prefix symbols nor collects imports.
  static const Allocator none = _NullAllocator();

  /// Creates a new default allocator that applies no prefixing.
  factory Allocator() = _Allocator;

  /// Creates a new allocator that applies naive prefixing to avoid conflicts.
  ///
  /// This implementation is not optimized for any particular code generation
  /// style and instead takes a conservative approach of prefixing _every_
  /// import except references to `dart:core` (which are considered always
  /// imported).
  ///
  /// The prefixes are not guaranteed to be stable and cannot be expected to
  /// have any particular value.
  factory Allocator.simplePrefixing() = _PrefixedAllocator;

  /// Returns a reference string given a [reference] object.
  ///
  /// For example, a no-op implementation:
  /// ```dart
  /// allocate(const Reference('List', 'dart:core')); // Returns 'List'.
  /// ```
  ///
  /// Where-as an implementation that prefixes imports might output:
  /// ```dart
  /// allocate(const Reference('Foo', 'package:foo')); // Returns '_i1.Foo'.
  /// ```
  String allocate(Reference reference);

  /// All imports that have so far been added implicitly via [allocate].
  Iterable<Directive> get imports;
}

class _Allocator implements Allocator {
  final _imports = <String>{};

  @override
  String allocate(Reference reference) {
    final url = reference.url;
    if (url != null) {
      _imports.add(url);
    }
    return reference.symbol!;
  }

  @override
  Iterable<Directive> get imports => _imports.map(Directive.import);
}

class _NullAllocator implements Allocator {
  const _NullAllocator();

  @override
  String allocate(Reference reference) => reference.symbol!;

  @override
  Iterable<Directive> get imports => const [];
}

class _PrefixedAllocator implements Allocator {
  static const _doNotPrefix = ['dart:core'];

  final _imports = <String, int>{};
  var _keys = 1;

  @override
  String allocate(Reference reference) {
    final symbol = reference.symbol;
    final url = reference.url;
    if (url == null || _doNotPrefix.contains(url)) {
      return symbol!;
    }
    return '_i${_imports.putIfAbsent(url, _nextKey)}.$symbol';
  }

  int _nextKey() => _keys++;

  @override
  Iterable<Directive> get imports => _imports.keys.map(
        (u) => Directive.import(u, as: '_i${_imports[u]}'),
      );
}
