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

import 'dart:math' as math;

import 'package:analysis_server/lsp_protocol/protocol.dart';
import 'package:analysis_server/src/lsp/constants.dart';
import 'package:analysis_server/src/lsp/semantic_tokens/mapping.dart';
import 'package:meta/meta.dart';

final semanticTokenLegend = SemanticTokenLegendLookup();

/// A helper for looking up indexes and bitmasks of [SemanticTokenTypes] and
/// [SemanticTokenModifiers].
class SemanticTokenLegendLookup {
  /// An LSP [SemanticTokensLegend] describing all supported tokens and modifiers.
  late SemanticTokensLegend lspLegend;

  /// All [SemanticTokenModifiers] the server may generate. The order of these
  /// items is important as the indexes will be used in communication between
  /// server and client.
  late List<SemanticTokenModifiers> _usedTokenModifiers;

  /// All [SemanticTokenTypes] the server may generate. The order of these
  /// items is important as the indexes will be used in communication betewen
  /// server and client.
  late List<SemanticTokenTypes> _usedTokenTypes;

  SemanticTokenLegendLookup() {
    // Build lists of all tokens and modifiers that exist in our mappings or that
    // we have added as custom types. These will be used to determine the indexes used for communication.
    _usedTokenTypes = Set.of(highlightRegionTokenTypes.values
            .followedBy(CustomSemanticTokenTypes.values))
        .toList();
    _usedTokenModifiers = Set.of(highlightRegionTokenModifiers.values
            .expand((v) => v)
            .followedBy(CustomSemanticTokenModifiers.values))
        .toList();

    // Build the LSP Legend which tells the client all of the tokens and modifiers
    // we will use in the order they should be accessed by index/bit.
    lspLegend = SemanticTokensLegend(
      tokenTypes:
          _usedTokenTypes.map((tokenType) => tokenType.toString()).toList(),
      tokenModifiers: _usedTokenModifiers
          .map((tokenModifier) => tokenModifier.toString())
          .toList(),
    );
  }

  int bitmaskForModifiers(Set<SemanticTokenModifiers>? modifiers) {
    // Modifiers use a bit mask where each bit represents the index of a modifier.
    // 001001 would indicate the 1st and 4th modifiers are applied.
    return modifiers
            ?.map(_usedTokenModifiers.indexOf)
            .map((index) => math.pow(2, index))
            .reduce((a, b) => a + b)
            .toInt() ??
        0;
  }

  int indexForType(SemanticTokenTypes type) {
    return _usedTokenTypes.indexOf(type);
  }

  /// Gets the [SemanticTokenModifiers] for a given index.
  @visibleForTesting
  List<SemanticTokenModifiers> modifiersForBitmask(int mask) {
    final modifiers = <SemanticTokenModifiers>[];
    for (var i = 0; i < _usedTokenModifiers.length; i++) {
      // Check if the i'th bit is set
      final modifierBit = 1 << i;
      if (mask & modifierBit != 0) {
        modifiers.add(_usedTokenModifiers[i]);
      }
    }
    return modifiers;
  }

  /// Gets the [SemanticTokenTypes] for a given index.
  @visibleForTesting
  SemanticTokenTypes typeForIndex(int index) => _usedTokenTypes[index];
}
