// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.

package org.intellij.sdk.language;

import com.intellij.lang.annotation.AnnotationBuilder;
import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.Annotator;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiLiteralExpression;
import org.intellij.sdk.language.psi.SimpleProperty;
import org.jetbrains.annotations.NotNull;

import java.util.List;

public class SimpleAnnotator implements Annotator {

  // Define strings for the Simple language prefix - used for annotations, line markers, etc.
  public static final String SIMPLE_PREFIX_STR = "simple";
  public static final String SIMPLE_SEPARATOR_STR = ":";

  @Override
  public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) {
    // Ensure the Psi Element is an expression
    if (!(element instanceof PsiLiteralExpression)) {
      return;
    }

    // Ensure the Psi element contains a string that starts with the prefix and separator
    PsiLiteralExpression literalExpression = (PsiLiteralExpression) element;
    String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null;
    if ((value == null) || !value.startsWith(SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR)) {
      return;
    }

    // Define the text ranges (start is inclusive, end is exclusive)
    // "simple:key"
    //  01234567890
    TextRange prefixRange = TextRange.from(element.getTextRange().getStartOffset(), SIMPLE_PREFIX_STR.length() + 1);
    TextRange separatorRange = TextRange.from(prefixRange.getEndOffset(), SIMPLE_SEPARATOR_STR.length());
    TextRange keyRange = new TextRange(separatorRange.getEndOffset(), element.getTextRange().getEndOffset() - 1);

    // Get the list of properties from the Project
    String possibleProperties = value.substring(SIMPLE_PREFIX_STR.length() + SIMPLE_SEPARATOR_STR.length());
    Project project = element.getProject();
    List<SimpleProperty> properties = SimpleUtil.findProperties(project, possibleProperties);

    // Set the annotations using the text ranges - Normally there would be one range, set by the element itself.
    holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
            .range(prefixRange).textAttributes(DefaultLanguageHighlighterColors.KEYWORD).create();
    holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
            .range(separatorRange).textAttributes(SimpleSyntaxHighlighter.SEPARATOR).create();
    if (properties.isEmpty()) {
      // No well-formed property found following the key-separator
      AnnotationBuilder builder = holder.newAnnotation(HighlightSeverity.ERROR, "Unresolved property").range(keyRange);
      // Force the text attributes to Simple syntax bad character
      builder.textAttributes(SimpleSyntaxHighlighter.BAD_CHARACTER);
      // ** Tutorial step 18.3 - Add a quick fix for the string containing possible properties
      builder.withFix(new SimpleCreatePropertyQuickFix(possibleProperties));
      // Finish creating new annotation
      builder.create();
    } else {
      // Found at least one property, force the text attributes to Simple syntax value character
      holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
              .range(keyRange).textAttributes(SimpleSyntaxHighlighter.VALUE).create();
    }
  }

}

@@ -219,41 +219,43 @@
 lij.
-lang.annotation.AnnotationBuilder
+codeInspection.ProblemHighlightType
 ;%0Aim
@@ -481,53 +481,8 @@
 rs;%0A
-import com.intellij.openapi.project.Project;%0A
 impo
@@ -2065,412 +2065,51 @@
  // 
-Get the list of properties from the Project%0A    String possibleProperties = value.substring(SIMPLE_PREFIX_STR.length() + SIMPLE_SEPARATOR_STR.length());%0A    Project project = element.getProject();%0A    List%3CSimpleProperty%3E properties = SimpleUtil.findProperties(project, possibleProperties);%0A%0A    // Set the annotations using the text ranges - Normally there would be one range, set by the element itself.
+highlight %22simple%22 prefix and %22:%22 separator
 %0A   
@@ -2423,24 +2423,41 @@
 eate();%0A
+%0A%0A
     
-i
+// Get the list o
 f 
-(
 properti
@@ -2462,122 +2462,246 @@
 ties
-.isEmpty()) %7B%0A      // No well-formed property found following the key-separator%0A      AnnotationBuilder builder =
+ for given key%0A    String key = value.substring(SIMPLE_PREFIX_STR.length() + SIMPLE_SEPARATOR_STR.length());%0A    List%3CSimpleProperty%3E properties = SimpleUtil.findProperties(element.getProject(), key);%0A    if (properties.isEmpty()) %7B%0A     
  hol
@@ -2765,16 +2765,31 @@
 operty%22)
+%0A              
 .range(k
@@ -2800,145 +2800,88 @@
 nge)
-;
 %0A      
-// Force the text attributes to Simple syntax bad character%0A      builder.textAttributes(SimpleSyntaxHighlighter.BAD_CHARACTER);%0A
+        .highlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL)%0A        
     
@@ -2977,23 +2977,24 @@
 s%0A      
-builder
+        
 .withFix
@@ -3031,83 +3031,28 @@
 Fix(
-possibleProperties
+key
 ))
-;
 %0A      
-// Finish creating new annotation%0A      builder
+        
 .cre

simple language: improve SimpleAnnotator