/*
 * 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.buildfile.parser;

import com.google.common.collect.Lists;
import com.google.idea.blaze.base.lang.buildfile.lexer.BuildLexer;
import com.google.idea.blaze.base.lang.buildfile.lexer.BuildLexerBase;
import com.google.idea.blaze.base.lang.buildfile.lexer.BuildToken;
import com.google.idea.blaze.base.lang.buildfile.lexer.TokenKind;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildElementType;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildElementTypes;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.google.idea.common.experiments.DeveloperFlag;
import com.intellij.extapi.psi.ASTWrapperPsiElement;
import com.intellij.lang.ASTNode;
import com.intellij.lang.ParserDefinition;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiParser;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.project.Project;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.source.resolve.FileContextUtil;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.IFileElementType;
import com.intellij.psi.tree.TokenSet;

/** Defines the BUILD file parser */
public class BuildParserDefinition implements ParserDefinition {

  private static final DeveloperFlag DEBUG = new DeveloperFlag("build.file.debug.mode");

  @Override
  public Lexer createLexer(Project project) {
    return new BuildLexer(BuildLexerBase.LexerMode.Parsing);
  }

  @Override
  public PsiParser createParser(Project project) {
    return new BuildParser();
  }

  @Override
  public IFileElementType getFileNodeType() {
    return BuildElementTypes.BUILD_FILE;
  }

  @Override
  public TokenSet getWhitespaceTokens() {
    return convert(TokenKind.WHITESPACE, TokenKind.ILLEGAL);
  }

  @Override
  public TokenSet getCommentTokens() {
    return convert(TokenKind.COMMENT);
  }

  @Override
  public TokenSet getStringLiteralElements() {
    return convert(TokenKind.STRING);
  }

  @Override
  public PsiElement createElement(ASTNode node) {
    IElementType type = node.getElementType();
    if (type instanceof BuildElementType) {
      return ((BuildElementType) type).createElement(node);
    }
    return new ASTWrapperPsiElement(node);
  }

  @Override
  public PsiFile createFile(FileViewProvider viewProvider) {
    return new BuildFile(viewProvider);
  }

  @Override
  public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) {
    return SpaceRequirements.MAY;
  }

  private static TokenSet convert(TokenKind... blazeTokens) {
    return TokenSet.create(
        Lists.newArrayList(blazeTokens)
            .stream()
            .map(BuildToken::fromKind)
            .toArray(IElementType[]::new));
  }

  private static class BuildParser implements PsiParser {
    @Override
    public ASTNode parse(IElementType root, PsiBuilder builder) {
      if (DEBUG.getValue()) {
        System.err.println(builder.getUserDataUnprotected(FileContextUtil.CONTAINING_FILE_KEY));
      }
      PsiBuilder.Marker rootMarker = builder.mark();
      ParsingContext context = new ParsingContext(builder);
      context.statementParser.parseFileInput();
      rootMarker.done(root);
      return builder.getTreeBuilt();
    }
  }
}
