/*
 * Copyright 2008 Google Inc.
 * 
 * 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.gwt.dev.javac;

import com.google.gwt.dev.javac.testing.impl.JavaResourceBase;
import com.google.gwt.dev.javac.testing.impl.MockResource;

import junit.framework.TestCase;

import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

/**
 * Validates certain JDT behaviors that the compilation process may depend on
 * for correctness. One useful aspect would be that if we upgrade JDT in the
 * future, this test could help validate our assumptions.
 */
public class JdtBehaviorTest extends TestCase {

  /**
   * Hook-point if we need to modify the compiler behavior.
   */
  private static class CompilerImpl extends Compiler {

    public CompilerImpl(INameEnvironment environment,
        ICompilerRequestor requestor) {
      super(environment, DefaultErrorHandlingPolicies.proceedWithAllProblems(),
          JdtCompiler.getCompilerOptions(), requestor,
          new DefaultProblemFactory(Locale.getDefault()));
    }
  }

  /**
   * Hook point to accept results.
   */
  private class ICompilerRequestorImpl implements ICompilerRequestor {
    public void acceptResult(CompilationResult result) {
      if (result.hasErrors()) {
        StringBuilder sb = new StringBuilder();
        for (CategorizedProblem problem : result.getErrors()) {
          sb.append(problem.toString());
          sb.append('\n');
        }
        fail(sb.toString());
      }
      for (ClassFile classFile : result.getClassFiles()) {
        char[][] classNameArray = classFile.getCompoundName();
        char[][] packageArray = CharOperation.subarray(classNameArray, 0,
            classNameArray.length - 1);
        char[] packageName = CharOperation.concatWith(packageArray, '.');
        char[] className = CharOperation.concatWith(classNameArray, '.');
        addPackages(String.valueOf(packageName));
        classFiles.put(String.valueOf(className), classFile);
      }
    }

    private void addPackages(String packageName) {
      while (true) {
        packages.add(String.valueOf(packageName));
        int pos = packageName.lastIndexOf('.');
        if (pos > 0) {
          packageName = packageName.substring(0, pos);
        } else {
          packages.add("");
          break;
        }
      }
    }
  }

  /**
   * How JDT receives files from the environment.
   */
  private class INameEnvironmentImpl implements INameEnvironment {
    public void cleanup() {
      // intentionally blank
    }

    public NameEnvironmentAnswer findType(char[] type, char[][] pkg) {
      return findType(CharOperation.arrayConcat(pkg, type));
    }

    public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
      final char[] typeChars = CharOperation.concatWith(compoundTypeName, '.');
      String typeName = String.valueOf(typeChars);
      // System.out.println("findType: " + typeName);
      ClassFile classFile = classFiles.get(typeName);
      if (classFile != null) {
        try {
          byte[] bytes = classFile.getBytes();
          char[] loc = classFile.fileName();
          ClassFileReader cfr = new ClassFileReader(bytes, loc);
          return new NameEnvironmentAnswer(cfr, null);
        } catch (ClassFormatException e) {
          throw new RuntimeException("Unexpectedly unable to parse class file",
              e);
        }
      }
      return null;
    }

    public boolean isPackage(char[][] parentPkg, char[] pkg) {
      final char[] pathChars = CharOperation.concatWith(parentPkg, pkg, '.');
      String packageName = String.valueOf(pathChars);
      // System.out.println("isPackage: " + packageName);
      return packages.contains(packageName);
    }
  }

  private static class ResourceAdapter implements ICompilationUnit {

    private final MockResource sourceFile;

    public ResourceAdapter(MockResource resource) {
      sourceFile = resource;
    }

    public char[] getContents() {
      return Shared.readSource(sourceFile).toCharArray();
    }

    public char[] getFileName() {
      return sourceFile.getLocation().toCharArray();
    }

    public char[] getMainTypeName() {
      return Shared.getShortName(Shared.getTypeName(sourceFile)).toCharArray();
    }

    public char[][] getPackageName() {
      return CharOperation.splitOn('.', Shared.getPackageName(
          Shared.getTypeName(sourceFile)).toCharArray());
    }

    @Override
    public String toString() {
      return sourceFile.toString();
    }
  }

  protected Map<String, ClassFile> classFiles = new HashMap<String, ClassFile>();

  /**
   * New object for each test case.
   */
  protected INameEnvironmentImpl environment = new INameEnvironmentImpl();

  protected Set<String> packages = new HashSet<String>();

  /**
   * New object for each test case.
   */
  protected ICompilerRequestorImpl requestor = new ICompilerRequestorImpl();

  /**
   * New object for each test case.
   */
  CompilerImpl compiler = new CompilerImpl(environment, requestor);

  public void testIncrementalBuild() {
    List<MockResource> resources = new ArrayList<MockResource>();
    Collections.addAll(resources, JavaResourceBase.getStandardResources());
    resources.add(JavaResourceBase.FOO);
    doCompile(resources);

    // Now incremental build the bar cup.
    doCompile(Arrays.asList(JavaResourceBase.BAR));
  }

  public void testSingleBuild() {
    List<MockResource> resources = new ArrayList<MockResource>();
    Collections.addAll(resources, JavaResourceBase.getStandardResources());
    resources.add(JavaResourceBase.FOO);
    resources.add(JavaResourceBase.BAR);
    doCompile(resources);
  }

  private void doCompile(List<? extends MockResource> resources) {
    ICompilationUnit[] icus = new ICompilationUnit[resources.size()];
    for (int i = 0; i < icus.length; ++i) {
      icus[i] = new ResourceAdapter(resources.get(i));
    }
    compiler.compile(icus);
  }
}
