/*
 * Copyright (c) 2013, the Dart project authors.
 * 
 * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
 * 
 * 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.dart.engine.parser;

import com.google.dart.engine.EngineTestCase;
import com.google.dart.engine.ast.CompilationUnit;
import com.google.dart.engine.error.GatheringErrorListener;
import com.google.dart.engine.scanner.CharSequenceReader;
import com.google.dart.engine.scanner.IncrementalScanner;
import com.google.dart.engine.scanner.Scanner;
import com.google.dart.engine.scanner.Token;
import com.google.dart.engine.source.Source;
import com.google.dart.engine.source.TestSource;
import com.google.dart.engine.utilities.ast.AstComparator;

public class IncrementalParserTest extends EngineTestCase {
  public void fail_replace_identifier_with_functionLiteral_in_initializer() {
    // Function literals aren't allowed inside initializers; incremental parsing needs to gather
    // the appropriate context.
    //
    // "class A { var a; A(b) : a = b ? b : 0 { } }"
    // "class A { var a; A(b) : a = b ? () {} : 0 { } }"
    assertParse("class A { var a; A(b) : a = b ? ", "b", "() {}", " : 0 { } }");
  }

  public void test_delete_everything() {
    // "f() => a + b;"
    // ""
    assertParse("", "f() => a + b;", "", "");
  }

  public void test_delete_identifier_beginning() {
    // "f() => abs + b;"
    // "f() => s + b;"
    assertParse("f() => ", "ab", "", "s + b;");
  }

  public void test_delete_identifier_end() {
    // "f() => abs + b;"
    // "f() => a + b;"
    assertParse("f() => a", "bs", "", " + b;");
  }

  public void test_delete_identifier_middle() {
    // "f() => abs + b;"
    // "f() => as + b;"
    assertParse("f() => a", "b", "", "s + b;");
  }

  public void test_delete_mergeTokens() {
    // "f() => a + b + c;"
    // "f() => ac;"
    assertParse("f() => a", " + b + ", "", "c;");
  }

  public void test_insert_afterIdentifier1() {
    // "f() => a + b;"
    // "f() => abs + b;"
    assertParse("f() => a", "", "bs", " + b;");
  }

  public void test_insert_afterIdentifier2() {
    // "f() => a + b;"
    // "f() => a + bar;"
    assertParse("f() => a + b", "", "ar", ";");
  }

  public void test_insert_beforeIdentifier1() {
    // "f() => a + b;"
    // "f() => xa + b;"
    assertParse("f() => ", "", "x", "a + b;");
  }

  public void test_insert_beforeIdentifier2() {
    // "f() => a + b;"
    // "f() => a + xb;"
    assertParse("f() => a + ", "", "x", "b;");
  }

  public void test_insert_convertOneFunctionToTwo() {
    // "f() {}"
    // "f() => 0; g() {}"
    assertParse("f()", "", " => 0; g()", " {}");
  }

  public void test_insert_end() {
    // "class A {}"
    // "class A {} class B {}"
    assertParse("class A {}", "", " class B {}", "");
  }

  public void test_insert_insideClassBody() {
    // "class C {C(); }"
    // "class C { C(); }"
    assertParse("class C {", "", " ", "C(); }");
  }

  public void test_insert_insideIdentifier() {
    // "f() => cob;"
    // "f() => cow.b;"
    assertParse("f() => co", "", "w.", "b;");
  }

  public void test_insert_newIdentifier1() {
    // "f() => a; c;"
    // "f() => a; b c;"
    assertParse("f() => a;", "", " b", " c;");
  }

  public void test_insert_newIdentifier2() {
    // "f() => a;  c;"
    // "f() => a;b  c;"
    assertParse("f() => a;", "", "b", "  c;");
  }

  public void test_insert_newIdentifier3() {
    // "/** A simple function. */ f() => a; c;"
    // "/** A simple function. */ f() => a; b c;"
    assertParse("/** A simple function. */ f() => a;", "", " b", " c;");
  }

  public void test_insert_newIdentifier4() {
    // "/** An [A]. */ class A {} class B { m() { return 1; } }"
    // "/** An [A]. */ class A {} class B { m() { return 1 + 2; } }"
    assertParse("/** An [A]. */ class A {} class B { m() { return 1", "", " + 2", "; } }");
  }

  public void test_insert_period() {
    // "f() => a + b;"
    // "f() => a + b.;"
    assertParse("f() => a + b", "", ".", ";");
  }

  public void test_insert_period_betweenIdentifiers1() {
    // "f() => a b;"
    // "f() => a. b;"
    assertParse("f() => a", "", ".", " b;");
  }

  public void test_insert_period_betweenIdentifiers2() {
    // "f() => a b;"
    // "f() => a .b;"
    assertParse("f() => a ", "", ".", "b;");
  }

  public void test_insert_period_betweenIdentifiers3() {
    // "f() => a  b;"
    // "f() => a . b;"
    assertParse("f() => a ", "", ".", " b;");
  }

  public void test_insert_period_insideExistingIdentifier() {
    // "f() => ab;"
    // "f() => a.b;"
    assertParse("f() => a", "", ".", "b;");
  }

  public void test_insert_periodAndIdentifier() {
    // "f() => a + b;"
    // "f() => a + b.x;"
    assertParse("f() => a + b", "", ".x", ";");
  }

  public void test_insert_simpleToComplexExression() {
    // "/** An [A]. */ class A {} class B { m() => 1; }"
    // "/** An [A]. */ class A {} class B { m() => 1 + 2; }"
    assertParse("/** An [A]. */ class A {} class B { m() => 1", "", " + 2", "; }");
  }

  public void test_insert_whitespace_end() {
    // "f() => a + b;"
    // "f() => a + b; "
    assertParse("f() => a + b;", "", " ", "");
  }

  public void test_insert_whitespace_end_multiple() {
    // "f() => a + b;"
    // "f() => a + b;  "
    assertParse("f() => a + b;", "", "  ", "");
  }

  public void test_insert_whitespace_middle() {
    // "f() => a + b;"
    // "f() => a  + b;"
    assertParse("f() => a", "", " ", " + b;");
  }

  public void test_replace_identifier_beginning() {
    // "f() => bell + b;"
    // "f() => fell + b;"
    assertParse("f() => ", "b", "f", "ell + b;");
  }

  public void test_replace_identifier_end() {
    // "f() => bell + b;"
    // "f() => belt + b;"
    assertParse("f() => bel", "l", "t", " + b;");
  }

  public void test_replace_identifier_middle() {
    // "f() => first + b;"
    // "f() => frost + b;"
    assertParse("f() => f", "ir", "ro", "st + b;");
  }

  public void test_replace_multiple_partialFirstAndLast() {
    // "f() => aa + bb;"
    // "f() => ab * ab;"
    assertParse("f() => a", "a + b", "b * a", "b;");
  }

  public void test_replace_operator_oneForMany() {
    // "f() => a + b;"
    // "f() => a * c - b;"
    assertParse("f() => a ", "+", "* c -", " b;");
  }

  public void test_replace_operator_oneForOne() {
    // "f() => a + b;"
    // "f() => a * b;"
    assertParse("f() => a ", "+", "*", " b;");
  }

  /**
   * Given a description of the original and modified contents, perform an incremental scan of the
   * two pieces of text.
   * 
   * @param prefix the unchanged text before the edit region
   * @param removed the text that was removed from the original contents
   * @param added the text that was added to the modified contents
   * @param suffix the unchanged text after the edit region
   */
  private void assertParse(String prefix, String removed, String added, String suffix) {
    //
    // Compute the information needed to perform the test.
    //
    String originalContents = prefix + removed + suffix;
    String modifiedContents = prefix + added + suffix;
    int replaceStart = prefix.length();
    Source source = new TestSource();
    //
    // Parse the original contents.
    //
    GatheringErrorListener originalListener = new GatheringErrorListener();
    Scanner originalScanner = new Scanner(
        source,
        new CharSequenceReader(originalContents),
        originalListener);
    Token originalTokens = originalScanner.tokenize();
    assertNotNull(originalTokens);
    Parser originalParser = new Parser(source, originalListener);
    CompilationUnit originalUnit = originalParser.parseCompilationUnit(originalTokens);
    assertNotNull(originalUnit);
    //
    // Parse the modified contents.
    //
    GatheringErrorListener modifiedListener = new GatheringErrorListener();
    Scanner modifiedScanner = new Scanner(
        source,
        new CharSequenceReader(modifiedContents),
        modifiedListener);
    Token modifiedTokens = modifiedScanner.tokenize();
    assertNotNull(modifiedTokens);
    Parser modifiedParser = new Parser(source, modifiedListener);
    CompilationUnit modifiedUnit = modifiedParser.parseCompilationUnit(modifiedTokens);
    assertNotNull(modifiedUnit);
    //
    // Incrementally parse the modified contents.
    //
    GatheringErrorListener incrementalListener = new GatheringErrorListener();
    IncrementalScanner incrementalScanner = new IncrementalScanner(source, new CharSequenceReader(
        modifiedContents), incrementalListener);
    Token incrementalTokens = incrementalScanner.rescan(
        originalTokens,
        replaceStart,
        removed.length(),
        added.length());
    assertNotNull(incrementalTokens);
    IncrementalParser incrementalParser = new IncrementalParser(
        source,
        incrementalScanner.getTokenMap(),
        incrementalListener);
    CompilationUnit incrementalUnit = incrementalParser.reparse(
        originalUnit,
        incrementalScanner.getLeftToken(),
        incrementalScanner.getRightToken(),
        replaceStart,
        prefix.length() + removed.length());
    assertNotNull(incrementalUnit);
    //
    // Validate that the results of the incremental parse are the same as the full parse of the
    // modified source.
    //
    assertTrue(AstComparator.equalNodes(modifiedUnit, incrementalUnit));
    // TODO(brianwilkerson) Verify that the errors are correct?
  }
}
