// 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_generated.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];
}
