// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package fuchsia.developer.plugin.fidl;

import static com.intellij.openapi.editor.colors.TextAttributesKey.createTextAttributesKey;

import com.google.common.collect.ImmutableMap;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.fileTypes.SyntaxHighlighterBase;
import com.intellij.psi.tree.IElementType;
import fuchsia.developer.plugin.fidl.psi.Types;
import java.util.Arrays;
import java.util.Map;
import org.jetbrains.annotations.NotNull;

public class SyntaxHighlighter extends SyntaxHighlighterBase {
  public static final TextAttributesKey IDENTIFIER =
      createTextAttributesKey("IDENTIFIER", DefaultLanguageHighlighterColors.IDENTIFIER);
  private static final TextAttributesKey[] IDENTIFIER_KEYS = new TextAttributesKey[] {IDENTIFIER};

  public static final TextAttributesKey NUMBER =
      createTextAttributesKey("NUMERIC_LITERAL", DefaultLanguageHighlighterColors.NUMBER);
  private static final TextAttributesKey[] NUMBER_KEYS = new TextAttributesKey[] {NUMBER};

  public static final TextAttributesKey KEYWORD =
      createTextAttributesKey("KEYWORD", DefaultLanguageHighlighterColors.KEYWORD);
  private static final TextAttributesKey[] KEYWORD_KEYS = new TextAttributesKey[] {KEYWORD};

  public static final TextAttributesKey STRING =
      createTextAttributesKey("STRING", DefaultLanguageHighlighterColors.STRING);
  private static final TextAttributesKey[] STRING_KEYS = new TextAttributesKey[] {STRING};

  public static final TextAttributesKey LINE_COMMENT =
      createTextAttributesKey("LINE_COMMENT", DefaultLanguageHighlighterColors.LINE_COMMENT);
  private static final TextAttributesKey[] LINE_COMMENT_KEYS =
      new TextAttributesKey[] {LINE_COMMENT};

  public static final TextAttributesKey DOC_COMMENT =
      createTextAttributesKey("DOC_COMMENT", DefaultLanguageHighlighterColors.DOC_COMMENT);
  private static final TextAttributesKey[] DOC_COMMENT_KEYS = new TextAttributesKey[] {DOC_COMMENT};

  public static final TextAttributesKey BRACES =
      createTextAttributesKey("BRACES", DefaultLanguageHighlighterColors.BRACES);
  private static final TextAttributesKey[] BRACES_KEYS = new TextAttributesKey[] {BRACES};

  public static final TextAttributesKey AT =
      createTextAttributesKey("AT", DefaultLanguageHighlighterColors.MARKUP_ATTRIBUTE);
  private static final TextAttributesKey[] AT_KEYS = new TextAttributesKey[] {AT};

  public static final TextAttributesKey DOT =
      createTextAttributesKey("DOT", DefaultLanguageHighlighterColors.DOT);
  private static final TextAttributesKey[] DOT_KEYS = new TextAttributesKey[] {DOT};

  public static final TextAttributesKey SEMICOLON =
      createTextAttributesKey("SEMICOLON", DefaultLanguageHighlighterColors.SEMICOLON);
  private static final TextAttributesKey[] SEMICOLON_KEYS = new TextAttributesKey[] {SEMICOLON};

  public static final TextAttributesKey COMMA =
      createTextAttributesKey("COMMA", DefaultLanguageHighlighterColors.COMMA);
  private static final TextAttributesKey[] COMMA_KEYS = new TextAttributesKey[] {COMMA};

  public static final TextAttributesKey PARENTHESES =
      createTextAttributesKey("PARENTHESES", DefaultLanguageHighlighterColors.PARENTHESES);
  private static final TextAttributesKey[] PARENTHESES_KEYS = new TextAttributesKey[] {PARENTHESES};

  private static final TextAttributesKey[] EMPTY_KEYS = new TextAttributesKey[0];

  private static final Map<IElementType, TextAttributesKey[]> HIGHLIGHT_TYPES;

  static {
    ImmutableMap.Builder<IElementType, TextAttributesKey[]> builder = ImmutableMap.builder();
    for (IElementType key :
        Arrays.asList(
            Types.LIBRARY,
            Types.USING_T,
            Types.ALIAS,
            Types.AS,
            Types.BITS,
            Types.BYTES,
            Types.CONST,
            Types.ENUM,
            Types.INTERFACE,
            Types.PROTOCOL,
            Types.COMPOSE,
            Types.SERVICE,
            Types.TYPE,
            Types.STRUCT,
            Types.TABLE,
            Types.UNION,
            Types.XUNION,
            Types.ERROR,
            Types.RESERVED,
            Types.RESOURCE,
            Types.RESOURCE_DEFINITION,
            Types.PROPERTIES,
            Types.STRICT,
            Types.FLEXIBLE,
            Types.TRUE,
            Types.FALSE)) {
      builder.put(key, KEYWORD_KEYS);
    }
    builder.put(Types.IDENTIFIER, IDENTIFIER_KEYS);
    builder.put(Types.DECIMAL_FLOAT_LITERAL, NUMBER_KEYS);
    builder.put(Types.DECIMAL_INTEGRAL_LITERAL, NUMBER_KEYS);
    builder.put(Types.HEX_INTEGRAL_LITERAL, NUMBER_KEYS);
    builder.put(Types.BINARY_INTEGRAL_LITERAL, NUMBER_KEYS);
    builder.put(Types.STRING_LITERAL, STRING_KEYS);
    builder.put(Types.LINE_COMMENT, LINE_COMMENT_KEYS);
    builder.put(Types.DOC_COMMENT, DOC_COMMENT_KEYS);
    builder.put(Types.OBRACE, BRACES_KEYS);
    builder.put(Types.CBRACE, BRACES_KEYS);
    builder.put(Types.SEMICOLON, SEMICOLON_KEYS);
    builder.put(Types.AT, AT_KEYS);
    builder.put(Types.DOT, DOT_KEYS);
    builder.put(Types.COMMA, COMMA_KEYS);
    builder.put(Types.OPAREN, PARENTHESES_KEYS);
    builder.put(Types.CPAREN, PARENTHESES_KEYS);

    HIGHLIGHT_TYPES = builder.build();
  }

  @NotNull
  @Override
  public Lexer getHighlightingLexer() {
    return new LexerAdapter();
  }

  @NotNull
  @Override
  public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
    return HIGHLIGHT_TYPES.getOrDefault(tokenType, EMPTY_KEYS);
  }

  public TextAttributesKey[] getKeywordHighlights() {
    return KEYWORD_KEYS;
  }
}
