// 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 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};

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

  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.AS,
            Types.BITS,
            Types.BYTES,
            Types.CONST,
            Types.ENUM,
            Types.INTERFACE,
            Types.PROTOCOL,
            Types.COMPOSE,
            Types.STRUCT,
            Types.TABLE,
            Types.UNION,
            Types.XUNION,
            Types.ERROR,
            Types.ARRAY,
            Types.VECTOR,
            Types.STRING,
            Types.HANDLE,
            Types.PROCESS,
            Types.THREAD,
            Types.VMO,
            Types.CHANNEL,
            Types.EVENT,
            Types.PORT,
            Types.INTERRUPT,
            Types.LOG,
            Types.SOCKET,
            Types.RESOURCE,
            Types.EVENTPAIR,
            Types.JOB,
            Types.VMAR,
            Types.FIFO,
            Types.GUEST,
            Types.TIMER,
            Types.REQUEST,
            Types.RESERVED,
            Types.BOOL,
            Types.FLOAT32,
            Types.FLOAT64,
            Types.INT8,
            Types.INT16,
            Types.INT32,
            Types.INT64,
            Types.UINT8,
            Types.UINT16,
            Types.UINT32,
            Types.UINT64,
            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.DOT, DOT_KEYS);
    builder.put(Types.COMMA, COMMA_KEYS);
    builder.put(Types.OPAREN, PARENTHESES_KEYS);
    builder.put(Types.CPAREN, PARENTHESES_KEYS);
    builder.put(Types.OBRACKET, BRACKETS_KEYS);
    builder.put(Types.CBRACKET, BRACKETS_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);
  }
}
