/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.idea.blaze.base.lang.projectview.completion;

import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.lang.projectview.language.ProjectViewLanguage;
import com.google.idea.blaze.base.lang.projectview.lexer.ProjectViewTokenType;
import com.google.idea.blaze.base.projectview.section.ListSectionParser;
import com.google.idea.blaze.base.projectview.section.ScalarSectionParser;
import com.google.idea.blaze.base.projectview.section.SectionParser;
import com.google.idea.blaze.base.projectview.section.sections.Sections;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.Nullable;

import java.util.List;

import static com.intellij.patterns.PlatformPatterns.psiElement;

/**
 * Completes project view section names.
 */
public class ProjectViewKeywordCompletionContributor extends CompletionContributor {

  @Override
  public AutoCompletionDecision handleAutoCompletionPossibility(AutoCompletionContext context) {
    // auto-insert the obvious only case; else show other cases.
    final LookupElement[] items = context.getItems();
    if (items.length == 1) {
      return AutoCompletionDecision.insertItem(items[0]);
    }
    return AutoCompletionDecision.SHOW_LOOKUP;
  }

  public ProjectViewKeywordCompletionContributor() {
    extend(
      CompletionType.BASIC,
      psiElement()
        .withLanguage(ProjectViewLanguage.INSTANCE)
        .withElementType(ProjectViewTokenType.IDENTIFIERS)
        .andOr(
          psiElement().afterLeaf("\n"),
          psiElement().afterLeaf(psiElement().isNull())
        ),
      new CompletionProvider<CompletionParameters>() {
        @Override
        protected void addCompletions(CompletionParameters parameters, ProcessingContext context, CompletionResultSet result) {
          result.addAllElements(keywordLookups);
        }
      }
    );
  }

  private static final List<LookupElement> keywordLookups = getLookups();

  private static List<LookupElement> getLookups() {
    ImmutableList.Builder<LookupElement> list = ImmutableList.builder();
    for (SectionParser parser : Sections.getUndeprecatedParsers()) {
      list.add(forSectionParser(parser));
    }
    return list.build();
  }

  private static LookupElement forSectionParser(SectionParser parser) {
    return LookupElementBuilder.create(parser.getName())
      .withInsertHandler(insertDivider(parser));
  }

  private static InsertHandler<LookupElement> insertDivider(SectionParser parser) {
    return (context, item) -> {
      Editor editor = context.getEditor();
      Document document = editor.getDocument();
      context.commitDocument();

      String nextTokenText = findNextTokenText(context);
      if (nextTokenText == null || nextTokenText == "\n") {
        document.insertString(context.getTailOffset(), getDivider(parser));
        editor.getCaretModel().moveToOffset(context.getTailOffset());
      }
    };
  }

  private static String getDivider(SectionParser parser) {
    if (parser instanceof ListSectionParser) {
      return ":\n  ";
    }
    char div = ((ScalarSectionParser) parser).getDivider();
    return div == ' ' ? String.valueOf(div) : (div + " ");
  }

  @Nullable
  protected static String findNextTokenText(final InsertionContext context) {
    final PsiFile file = context.getFile();
    PsiElement element = file.findElementAt(context.getTailOffset());
    while (element != null && element.getTextLength() == 0) {
      ASTNode next = element.getNode().getTreeNext();
      element = next != null ? next.getPsi() : null;
    }
    return element != null ? element.getText() : null;
  }

}
