// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

package com.google.dart.compiler;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.dart.compiler.CommandLineOptions.CompilerOptions;
import com.google.dart.compiler.ast.ASTVisitor;
import com.google.dart.compiler.ast.DartExpression;
import com.google.dart.compiler.ast.DartFunctionTypeAlias;
import com.google.dart.compiler.ast.DartIdentifier;
import com.google.dart.compiler.ast.DartNode;
import com.google.dart.compiler.ast.DartUnit;
import com.google.dart.compiler.ast.LibraryUnit;
import com.google.dart.compiler.common.ErrorExpectation;
import com.google.dart.compiler.common.SourceInfo;
import com.google.dart.compiler.end2end.inc.MemoryLibrarySource;
import com.google.dart.compiler.parser.DartParser;
import com.google.dart.compiler.parser.DartParserRunner;
import com.google.dart.compiler.resolver.Element;
import com.google.dart.compiler.type.Type;
import com.google.dart.compiler.type.TypeQuality;

import static com.google.dart.compiler.common.ErrorExpectation.assertErrors;

import junit.framework.TestCase;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URI;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Base class for compiler tests, with helpful utility methods.
 */
public abstract class CompilerTestCase extends TestCase {

  private static final String UTF8 = "UTF-8";
  protected CompilerConfiguration compilerConfiguration;
  protected String testSource;
  protected DartUnit testUnit;

  /**
   * Instance of {@link CompilerConfiguration} for incremental check-only compilation.
   */
  protected static final CompilerConfiguration CHECK_ONLY_CONFIGURATION =
      new DefaultCompilerConfiguration(new CompilerOptions()) {
        @Override
        public boolean incremental() {
          return true;
        }

        @Override
        public boolean resolveDespiteParseErrors() {
          return true;
        }
      };

  /**
   * Read a resource from the given URL.
   */
  protected static String readUrl(URL url) {
    try {
      StringBuffer out = new StringBuffer();
      Reader in = new InputStreamReader(url.openStream(), UTF8);
      char[] buf = new char[10240];
      int n;
      while ((n = in.read(buf)) > 0) {
        out.append(buf, 0, n);
      }
      in.close();
      return out.toString();
    } catch (IOException e) {
      // Just punt a RuntimeException out the top if something goes wrong.
      // It will simply cause the test to fail, which is exactly what we want.
      throw new RuntimeException(e);
    }
  }

  /**
   * Return a URL that can be used to read an input file for the given test name
   * and path.
   */
  protected static URL inputUrlFor(Class<?> testClass, String testName) {
    String fullPath = testClass.getPackage().getName().replace('.', '/') + "/"
        + testName;
    URL url = chooseClassLoader().getResource(fullPath);
    if (url == null) {
      fail("Could not find input file: " + fullPath);
    }
    return url;
  }

  private static ClassLoader chooseClassLoader() {
    if (Thread.currentThread().getContextClassLoader() != null) {
      return Thread.currentThread().getContextClassLoader();
    }
    return CompilerTestCase.class.getClassLoader();
  }

  /**
   * Collects the results of running analyzeLibrary.
   */
  protected static class AnalyzeLibraryResult extends DartCompilerListener.Empty {
    public String source;
    private final List<DartCompilationError> errors = Lists.newArrayList();
    private final List<DartCompilationError> compilationErrors = Lists.newArrayList();
    private final List<DartCompilationError> compilationWarnings = Lists.newArrayList();
    private final List<DartCompilationError> typeErrors = Lists.newArrayList();
    private LibraryUnit result;

    @Override
    public void onError(DartCompilationError event) {
      errors.add(event);
      if (event.getErrorCode().getSubSystem() == SubSystem.STATIC_TYPE) {
        typeErrors.add(event);
      } else if (event.getErrorCode().getErrorSeverity() == ErrorSeverity.ERROR) {
        compilationErrors.add(event);
      }   else if (event.getErrorCode().getErrorSeverity() == ErrorSeverity.WARNING) {
        compilationWarnings.add(event);
      }
    }

    public List<DartCompilationError> getErrors() {
      return errors;
    }

    public List<DartCompilationError> getTypeErrors() {
      return typeErrors;
    }

    public List<DartCompilationError> getCompilationErrors() {
      return compilationErrors;
    }

    public List<DartCompilationError> getCompilationWarnings() {
      return compilationWarnings;
    }

    /**
     * @param lib
     */
    public void setLibraryUnitResult(LibraryUnit lib) {
      result = lib;
    }

    /**
     * @return the analyzed library
     */
    public LibraryUnit getLibraryUnitResult() {
      return result;
    }
  }

  /**
   * Build a multi-line string from a list of strings.
   *
   * @param lines
   * @return a single string containing {@code lines}, each terminated by \n
   */
  protected static String makeCode(String... lines) {
    StringBuilder buf = new StringBuilder();
    for (String line : lines) {
      buf.append(line).append('\n');
    }
    return buf.toString();
  }
  
  @Override
  protected void setUp() throws Exception {
    super.setUp();
    compilerConfiguration = CHECK_ONLY_CONFIGURATION;
  }

  @Override
  protected void tearDown() throws Exception {
    compilerConfiguration = null;
    testSource = null;
    testUnit = null;
    super.tearDown();
  }

  protected AnalyzeLibraryResult analyzeLibrary(String... lines) throws Exception {
    testSource = makeCode(lines);
    AnalyzeLibraryResult libraryResult = analyzeLibrary(testSource);
    testUnit = libraryResult.getLibraryUnitResult().getUnits().iterator().next();
    return libraryResult;
  }

  /**
   * Simulate running {@code analyzeLibrary} the way the IDE will.
   * <p>
   * <b>Note:</b> if the IDE changes how it calls analyzeLibrary, this should
   * be changed to match.
   * @param code the Dart code to parse/analyze
   *
   * @return an {@link AnalyzeLibraryResult} containing the {@link LibraryUnit}
   *     and all the errors/warnings generated from the supplied code
   * @throws Exception
   */
  protected AnalyzeLibraryResult analyzeLibrary(String code)
      throws Exception {
    AnalyzeLibraryResult result = new AnalyzeLibraryResult();
    result.source = code;
    // Prepare library.
    MemoryLibrarySource lib = new MemoryLibrarySource("Test.dart");
    lib.setContent("Test.dart", code);
    // Prepare unit.
    Map<URI, DartUnit> testUnits =  Maps.newHashMap();
    {
      DartSource src = lib.getSourceFor("Test.dart");
      DartUnit unit = makeParser(src, code, result).parseUnit();
      testUnits.put(src.getUri(), unit);
    }
    DartArtifactProvider provider = new MockArtifactProvider();
    result.setLibraryUnitResult(DartCompiler.analyzeLibrary(
        lib,
        testUnits,
        compilerConfiguration,
        provider,
        result));
    // TODO(zundel): One day, we want all AST nodes that are identifiers to point to
    // elements if they are resolved.  Uncommenting this line helps track missing elements
    // down.
    // ResolverAuditVisitor.exec(unit);
    return result;
  }

  /**
   * Compiles a single unit with a synthesized application.
   */
  protected DartSource compileSingleUnit(String name, String code,
       DartArtifactProvider provider) throws IOException {
     MockLibrarySource lib = new MockLibrarySource();
     DartSourceTest src = new DartSourceTest(name, code, lib);
     lib.addSource(src);
     CompilerConfiguration config = getCompilerConfiguration();
     DartCompilerListener listener = new DartCompilerListenerTest(src.getName());
     DartCompiler.compileLib(lib, config, provider, listener);
     return src;
  }

  /**
   * Allow tests to override the configuration used.
   */
  protected CompilerConfiguration getCompilerConfiguration() {
    return new DefaultCompilerConfiguration();
  }

  /**
   * Parse a single compilation unit for the given input file.
   */
  protected final DartUnit parseUnit(String path) {
    // final because we delegate to the method below, and only that one should
    // be overriden to do extra checks.
    URL url = inputUrlFor(getClass(), path);
    String source = readUrl(url);
    return parseUnit(path, source);
  }

  /**
   * Parse a single compilation unit for the name and source.
   */
  protected DartUnit parseUnit(String srcName, String sourceCode, Object... errors) {
    testSource = sourceCode;
    // TODO(jgw): We'll need to fill in the library parameter when testing multiple units.
    DartSourceTest src = new DartSourceTest(srcName, sourceCode, null);
    DartCompilerListenerTest listener = new DartCompilerListenerTest(srcName, errors);
    testUnit = makeParser(src, sourceCode, listener).parseUnit();
    listener.checkAllErrorsReported();
    return testUnit;
  }

  /**
   * Parse a single compilation unit for the name and source. The parse expects some kind of error,
   * but isn't picky about the actual contents. This is useful for testing parser recovery where we
   * don't want to make the test too brittle.
   */
  protected DartUnit parseUnitUnspecifiedErrors(String srcName, String sourceCode) {
    DartSourceTest src = new DartSourceTest(srcName, sourceCode, null);
    final List<DartCompilationError> errorsEncountered = Lists.newArrayList();
    DartCompilerListener listener = new DartCompilerListener.Empty() {
      @Override
      public void onError(DartCompilationError event) {
        errorsEncountered.add(event);
      }
    };
    DartUnit unit = makeParser(src, sourceCode, listener).parseUnit();
    assertTrue("Expected some compilation errors, got none.", errorsEncountered.size() > 0);
    return unit;
    }

    protected DartUnit parseUnitAsSystemLibrary(final String srcName, String sourceCode,
                                              Object... errors) {
    DartSourceTest src = new DartSourceTest(srcName, sourceCode, null) {
      @Override
      public URI getUri() {
        return URI.create("dart:core/" + srcName);
      }
    };
    DartCompilerListenerTest listener = new DartCompilerListenerTest(srcName, errors);
    DartUnit unit = makeParser(src, sourceCode, listener).parseUnit();
    listener.checkAllErrorsReported();
    return unit;
  }


  /**
   * Parse a single compilation unit with given name and source, and check for a set of expected errors.
   *
   * @param errors a sequence of errors represented as triples of the form
   *        (String msg, int line, int column) or
   *        (ErrorCode code, int line, int column)
   */
  protected DartUnit parseSourceUnitErrors(String sourceCode,  Object... errors) {
    String srcName = "Test.dart";
    DartSourceTest src = new DartSourceTest(srcName, sourceCode, null);
    DartCompilerListenerTest listener = new DartCompilerListenerTest(srcName, errors);
    DartUnit unit = makeParser(src, sourceCode, listener).parseUnit();
    listener.checkAllErrorsReported();
    return unit;
  }

  /**
   * Parse a single compilation unit for the given input file, and check for a
   * set of expected errors.
   *
   * @param errors a sequence of errors represented as triples of the form
   *        (String msg, int line, int column) or
   *        (ErrorCode code, int line, int column)
   */
  protected DartUnit parseUnitErrors(final String path, final Object... errors) {
    URL url = inputUrlFor(getClass(), path);
    String sourceCode = readUrl(url);
    // TODO(jgw): We'll need to fill in the library parameter when testing multiple units.
    DartSourceTest src = new DartSourceTest(path, sourceCode, null);
    DartCompilerListenerTest listener = new DartCompilerListenerTest(path, errors);
    DartUnit unit = makeParser(src, sourceCode, listener).parseUnit();
    listener.checkAllErrorsReported();
    return unit;
  }

  /**
   * Override this method to provide an alternate {@link DartParser}.
   */
  protected DartParser makeParser(Source src, String sourceCode,
      DartCompilerListener listener) {
    return new DartParser(src, sourceCode, false, Sets.<String>newHashSet(), listener, null);
  }

  /**
   * @return the {@link DartParserRunner} with parsed source. It can be used to request
   *         {@link DartUnit} or compilation problems.
   */
  protected final DartParserRunner parseSource(String code) {
    return DartParserRunner.parse(getName(), code, Integer.MAX_VALUE, false);
  }

  /**
   * Parses given source and checks parsing problems.
   */
  protected final DartParserRunner parseExpectErrors(String code,
      ErrorExpectation... expectedErrors) {
    DartParserRunner parserRunner = parseSource(code);
    List<DartCompilationError> errors = parserRunner.getErrors();
    assertErrors(errors, expectedErrors);
    return parserRunner;
  }

  /**
   * Parses given source and checks parsing problems.
   */
  protected final void parseExpectWarnings(String code, ErrorExpectation... expectedWarnings) {
    DartParserRunner runner =  DartParserRunner.parse(getName(), code, Integer.MAX_VALUE, true);
    List<DartCompilationError> errors = runner.getErrors();
    assertErrors(errors, expectedWarnings);
  }
  
  /**
   * Find node in {@link #testUnit} parsed form {@link #testSource}.
   */
  public <T extends DartNode> T findNode(final Class<T> clazz, String pattern) {
    final int index = testSource.indexOf(pattern);
    assertTrue(index != -1);
    final AtomicReference<T> result = new AtomicReference<T>();
    testUnit.accept(new ASTVisitor<Void>() {
      @Override
      @SuppressWarnings("unchecked")
      public Void visitNode(DartNode node) {
        SourceInfo sourceInfo = node.getSourceInfo();
        if (sourceInfo.getOffset() <= index
            && index < sourceInfo.getEnd()
            && clazz.isInstance(node)) {
          result.set((T) node);
        }
        return super.visitNode(node);
      }
    });
    return result.get();
  }

  /**
   * @return the {@link DartExpression} with given {@link DartNode#toSource()}. This is inaccurate approach, but good
   *         enough for specific tests.
   */
  @SuppressWarnings("unchecked")
  protected static <T extends DartNode> T findNodeBySource(DartNode rootNode, final String sampleSource) {
    final DartNode result[] = new DartNode[1];
    rootNode.accept(new ASTVisitor<Void>() {
      @Override
      public Void visitNode(DartNode node) {
        if (node.toSource().equals(sampleSource)) {
          result[0] = node;
        }
        return super.visitNode(node);
      }
    });
    return (T) result[0];
  }

  protected static DartFunctionTypeAlias findTypedef(DartNode rootNode, final String name) {
    final DartFunctionTypeAlias result[] = new DartFunctionTypeAlias[1];
    rootNode.accept(new ASTVisitor<Void>() {
      @Override
      public Void visitFunctionTypeAlias(DartFunctionTypeAlias node) {
        if (node.getName().getName().equals(name)) {
          result[0] = node;
        }
        return null;
      }
    });
    return result[0];
  }

  public static String getNodeSource(String code, DartNode node) {
    SourceInfo sourceInfo = node.getSourceInfo();
    return code.substring(sourceInfo.getOffset(), sourceInfo.getEnd());
  }

  /**
   * Asserts that parsed {@link DartUnit} has {@link DartExpression} with given source and its
   * {@link SourceInfo} points to the given source.
   */
  protected void assertNodeSourceInfo(String nodeSource) {
    DartNode node = findNode(DartNode.class, nodeSource);
    assertNotNull(node);
    SourceInfo sourceInfo = node.getSourceInfo();
    String actualSource = testSource.substring(sourceInfo.getOffset(), sourceInfo.getEnd());
    assertEquals(nodeSource, actualSource);
  }

  /**
   * Asserts that {@link Element} with given name has expected type.
   */
  protected static void assertInferredElementTypeString(
      DartUnit unit,
      String variableName,
      String expectedType,
      TypeQuality quality) {
    // find element
    Element element = getNamedElement(unit, variableName);
    assertNotNull(element);
    // check type
    Type actualType = element.getType();
    assertInferredElementTypeString(actualType, element.getName(), expectedType, quality);
  }

  protected static void assertInferredElementTypeString(
      Type actualType,
      String testName,
      String expectedType,
      TypeQuality quality) {
    assertEquals(testName, expectedType, getTypeSource(actualType));
    if (quality != null) {
      assertSame(quality, actualType.getQuality());
    }
  }

  /**
   * @return the source-like {@link String} for the given {@link Type}.
   */
  protected static String getTypeSource(Type actualType) {
    return actualType.toString();
  }

  /**
   * @return the {@link Element} with given name, may be <code>null</code>.
   */
  private static Element getNamedElement(DartUnit unit, final String name) {
    final Element[] result = {null};
    unit.accept(new ASTVisitor<Void>() {
      @Override
      public Void visitIdentifier(DartIdentifier node) {
        Element element = node.getElement();
        if (element != null && element.getName().equals(name)) {
          result[0] = element;
        }
        return super.visitIdentifier(node);
      }
    });
    return result[0];
  }
}
