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

part of 'namer.dart';

class FrequencyBasedNamer extends Namer
    with _MinifiedFieldNamer, _MinifiedOneShotInterceptorNamer
    implements js_ast.TokenFinalizer {
  @override
  late final FieldNamingRegistry fieldRegistry = FieldNamingRegistry(this);
  List<TokenName> tokens = [];

  final Map<NamingScope, TokenScope> _tokenScopes = {};

  @override
  String get genericInstantiationPrefix => r'$I';

  FrequencyBasedNamer(super.closedWorld, super.fixedNames);

  TokenScope newScopeFor(NamingScope scope) {
    if (scope == instanceScope) {
      Set<String> illegalNames = Set<String>.from(jsReserved);
      for (String illegal in MinifyNamer._reservedNativeProperties) {
        illegalNames.add(illegal);
        if (hasBannedMinifiedPrefix(illegal)) {
          illegalNames.add(illegal.substring(1));
        }
      }
      return TokenScope(illegalNames: illegalNames);
    } else {
      return TokenScope(illegalNames: jsReserved);
    }
  }

  @override
  js_ast.Name getFreshName(
    NamingScope scope,
    String proposedName, {
    bool sanitizeForNatives = false,
    bool sanitizeForAnnotations = false,
  }) {
    // Grab the scope for this token
    TokenScope tokenScope = _tokenScopes.putIfAbsent(
      scope,
      () => newScopeFor(scope),
    );

    // Get the name the normal namer would use as a key.
    String proposed = _generateFreshStringForName(
      proposedName,
      scope,
      sanitizeForNatives: sanitizeForNatives,
      sanitizeForAnnotations: sanitizeForAnnotations,
    );

    TokenName name = TokenName(tokenScope, proposed);
    tokens.add(name);
    return name;
  }

  @override
  js_ast.Name instanceFieldPropertyName(FieldEntity element) {
    js_ast.Name? proposed = _minifiedInstanceFieldPropertyName(element);
    if (proposed != null) {
      return proposed;
    }
    return super.instanceFieldPropertyName(element);
  }

  @override
  void finalizeTokens() {
    int compareReferenceCount(TokenName a, TokenName b) {
      int result = b._rc - a._rc;
      if (result == 0) result = a.key.compareTo(b.key);
      return result;
    }

    List<TokenName> usedNames = tokens
        .where((TokenName a) => a._rc > 0)
        .toList();
    usedNames.sort(compareReferenceCount);
    for (var token in usedNames) {
      token.finalize();
    }
  }
}
