/*
 * 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.impl.JavaResourceBase;
import com.google.gwt.dev.javac.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);
  }
}
