/*
 * Copyright 2000-2013 JetBrains s.r.o.
 *
 * 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.intellij.lang.psi;

import com.intellij.lang.*;
import com.intellij.lang.impl.PsiBuilderImpl;
import com.intellij.lang.java.JavaParserDefinition;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.source.DummyHolder;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.SharedImplUtil;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.text.BlockSupport;
import com.intellij.testFramework.LightIdeaTestCase;
import junit.framework.AssertionFailedError;

/**
 * @since Jan 21, 2005
 * @author max
 */
public class PsiBuilderTest extends LightIdeaTestCase {
  private PsiBuilderImpl myBuilder;

  public void testEmptyProgram() throws Exception {
    myBuilder = createBuilder("");
    final PsiBuilder.Marker fileMarker = myBuilder.mark();
    fileMarker.done(JavaStubElementTypes.JAVA_FILE);
    ASTNode fileNode = myBuilder.getTreeBuilt();
    assertNotNull(fileNode);
    assertEquals("", fileNode.getText());
  }

  public void testProgramWithSingleKeyword() throws Exception {
    myBuilder = createBuilder("package");

    final PsiBuilder.Marker fileMarker = myBuilder.mark();
    assertEquals("package", myBuilder.getTokenText());
    assertEquals(JavaTokenType.PACKAGE_KEYWORD, myBuilder.getTokenType());
    final PsiBuilder.Marker packageStatementMarker = myBuilder.mark();
    myBuilder.advanceLexer();
    assertTrue(myBuilder.eof());
    packageStatementMarker.done(JavaElementType.PACKAGE_STATEMENT);
    fileMarker.done(JavaStubElementTypes.JAVA_FILE);

    ASTNode fileNode = myBuilder.getTreeBuilt();
    assertNotNull(fileNode);
    assertEquals("package", fileNode.getText());
    assertSame(fileNode.getFirstChildNode(), fileNode.getLastChildNode());
    ASTNode packageNode = fileNode.getFirstChildNode();
    assertNotNull(packageNode);
    assertEquals("package", packageNode.getText());
    assertEquals(JavaElementType.PACKAGE_STATEMENT, packageNode.getElementType());

    ASTNode leaf = packageNode.getFirstChildNode();
    assertNotNull(leaf);
    assertEquals(JavaTokenType.PACKAGE_KEYWORD, leaf.getElementType());
  }

  private static PsiBuilderImpl createBuilder(final String text) {
    return createBuilder(text,null);
  }
  private static PsiBuilderImpl createBuilder(final String text, ASTNode originalTree) {
    final Language lang = StdFileTypes.JAVA.getLanguage();
    final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
    assertNotNull(parserDefinition);
    PsiFile psiFile = createFile("x.java", text);
    return new PsiBuilderImpl(getProject(), psiFile, parserDefinition, JavaParserDefinition.createLexer(LanguageLevel.JDK_1_5),
                              SharedImplUtil.findCharTableByTree(psiFile.getNode()), text, originalTree, null);
  }

  public void testTrailingWhitespaces() throws Exception {
    myBuilder = createBuilder("foo\n\nx");
    final PsiBuilder.Marker marker = myBuilder.mark();
    while (!myBuilder.eof()) {
      myBuilder.advanceLexer();
    }
    marker.done(JavaStubElementTypes.JAVA_FILE);
    assertEquals("foo\n\nx", myBuilder.getTreeBuilt().getText());
  }

  public void testRollback() throws Exception {
    myBuilder = createBuilder("package");

    PsiBuilder.Marker fileMarker = myBuilder.mark();
    assertEquals("package", myBuilder.getTokenText());
    assertEquals(JavaTokenType.PACKAGE_KEYWORD, myBuilder.getTokenType());
    PsiBuilder.Marker packageStatementMarker = myBuilder.mark();
    myBuilder.advanceLexer();
    assertTrue(myBuilder.eof());
    packageStatementMarker.done(JavaElementType.PACKAGE_STATEMENT);

    fileMarker.rollbackTo();

    fileMarker = myBuilder.mark();
    assertEquals("package", myBuilder.getTokenText());
    assertEquals(JavaTokenType.PACKAGE_KEYWORD, myBuilder.getTokenType());
    packageStatementMarker = myBuilder.mark();
    myBuilder.advanceLexer();
    assertTrue(myBuilder.eof());
    packageStatementMarker.done(JavaElementType.PACKAGE_STATEMENT);
    fileMarker.done(JavaStubElementTypes.JAVA_FILE);

    ASTNode fileNode = myBuilder.getTreeBuilt();
    assertNotNull(fileNode);
    assertEquals("package", fileNode.getText());
    assertSame(fileNode.getFirstChildNode(), fileNode.getLastChildNode());
    ASTNode packageNode = fileNode.getFirstChildNode();
    assertNotNull(packageNode);
    assertEquals("package", packageNode.getText());
    assertEquals(JavaElementType.PACKAGE_STATEMENT, packageNode.getElementType());

    ASTNode leaf = packageNode.getFirstChildNode();
    assertNotNull(leaf);
    assertEquals(JavaTokenType.PACKAGE_KEYWORD, leaf.getElementType());
  }

  public void testDrop() throws Exception {
    myBuilder = createBuilder("package");

    final PsiBuilder.Marker fileMarker = myBuilder.mark();
    assertEquals("package", myBuilder.getTokenText());
    assertEquals(JavaTokenType.PACKAGE_KEYWORD, myBuilder.getTokenType());
    final PsiBuilder.Marker packageStatementMarker = myBuilder.mark();
    myBuilder.advanceLexer();
    assertTrue(myBuilder.eof());
    packageStatementMarker.drop();
    fileMarker.done(JavaStubElementTypes.JAVA_FILE);

    ASTNode fileNode = myBuilder.getTreeBuilt();
    assertNotNull(fileNode);
    assertEquals("package", fileNode.getText());
    assertSame(fileNode.getFirstChildNode(), fileNode.getLastChildNode());

    ASTNode leaf = fileNode.getFirstChildNode();
    assertNotNull(leaf);
    assertEquals(JavaTokenType.PACKAGE_KEYWORD, leaf.getElementType());
    assertEquals("package", leaf.getText());
    assertNull(leaf.getFirstChildNode());
  }

  public void testAdvanceBeyondEof() {
    myBuilder = createBuilder("package");
    for(int i=0; i<20; i++) {
      myBuilder.eof();
      myBuilder.advanceLexer();
    }
    assertTrue(myBuilder.eof());
  }

  public void testAssertionFailureOnUnbalancedMarkers() {
    myBuilder = createBuilder("foo");
    myBuilder.setDebugMode(true);
    PsiBuilder.Marker m = myBuilder.mark();
    @SuppressWarnings("UnusedDeclaration") PsiBuilder.Marker m1 = myBuilder.mark();
    myBuilder.getTokenType();
    myBuilder.advanceLexer();
    try {
      m.done(JavaTokenType.PACKAGE_KEYWORD);
      fail("Assertion must fire");
    }
    catch (AssertionFailedError e) {
      throw e;
    }
    catch (Throwable e) {
      if (!e.getMessage().startsWith("Another not done marker")) {
        fail("Wrong assertion message");
      }
    }
  }

  public void testNotAllTokensProcessed() {
    myBuilder = createBuilder("foo");
    myBuilder.setDebugMode(true);
    final PsiBuilder.Marker m = myBuilder.mark();
    m.done(JavaTokenType.PACKAGE_KEYWORD);
    try {
      myBuilder.getTreeBuilt();
      fail("Assertion must fire");
    }
    catch (AssertionFailedError e) {
      throw e;
    }
    catch (Throwable e) {
      if (!e.getMessage().startsWith("Tokens [IDENTIFIER] were not inserted into the tree")) {
        fail("Wrong assertion message");
      }
    }
  }

  public void testMergeWhenEmptyElementAfterWhitespaceIsLastChild() throws Throwable {
    myBuilder = createBuilder(" foo bar");
    parseWhenEmptyElementAfterWhitespaceIsLastChild();
    final ASTNode tree = myBuilder.getTreeBuilt();
    new DummyHolder(getPsiManager(), (TreeElement)tree, null);

    myBuilder = createBuilder("  bar", tree);
    parseWhenEmptyElementAfterWhitespaceIsLastChild();
    DebugUtil.startPsiModification(null);
    try {
      myBuilder.getTreeBuilt();
      fail();
    }
    catch (BlockSupport.ReparsedSuccessfullyException e) {
      e.getDiffLog().performActualPsiChange(tree.getPsi().getContainingFile());
    }
    finally {
      DebugUtil.finishPsiModification();
    }

    assertEquals("  bar", tree.getText());
  }

  private void parseWhenEmptyElementAfterWhitespaceIsLastChild() {
    final PsiBuilder.Marker root = myBuilder.mark();

    final PsiBuilder.Marker composite = myBuilder.mark();
    final PsiBuilder.Marker backup = myBuilder.mark();
    if ("foo".equals(myBuilder.getTokenText())) {
      myBuilder.advanceLexer();
      myBuilder.getTokenType();
      myBuilder.mark().done(JavaStubElementTypes.TYPE_PARAMETER_LIST);
      backup.done(JavaStubElementTypes.ANNOTATION_METHOD);
    } else {
      backup.rollbackTo();
    }
    composite.done(JavaStubElementTypes.ANONYMOUS_CLASS);

    myBuilder.getTokenType();
    myBuilder.advanceLexer();
    root.done(JavaStubElementTypes.ENUM_CONSTANT_INITIALIZER);
  }
}
