/*
 * Copyright 2011 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.web.bindery.requestfactory.apt;

import com.google.gwt.dev.util.Name.BinaryName;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;

import javax.lang.model.SourceVersion;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;

/**
 * Provides "late" validation services when server types aren't available to the
 * shared-interface compilation process. This tool is provided the name of an
 * output jar and the binary names of RequestFactory interfaces that should be
 * validated. The validation process will provide pre-computed type map builders
 * for use by the ServiceLayer.
 * 
 * @see http://code.google.com/p/google-web-toolkit/wiki/
 *      RequestFactoryInterfaceValidation
 */
public class ValidationTool {
  /**
   * A JavaFileManager that writes the class outputs into a jar file or a
   * directory.
   */
  static class JarOrDirectoryOutputFileManager extends ForwardingJavaFileManager<JavaFileManager> {
    private final List<MemoryJavaFileObject> toOutput = new ArrayList<MemoryJavaFileObject>();
    private final File output;

    JarOrDirectoryOutputFileManager(File output, JavaFileManager fileManager) {
      super(fileManager);
      this.output = output;
    }

    @Override
    public void close() throws IOException {
      if (output.isDirectory()) {
        writeToDirectory();
      } else {
        writeToJar();
      }
    }

    /**
     * Not expected to be called. Overridden to prevent accidental writes to
     * disk.
     */
    @Override
    public FileObject getFileForOutput(Location location, String packageName, String relativeName,
        FileObject sibling) throws IOException {
      throw new UnsupportedOperationException("Not expecting to write " + packageName + "/"
          + relativeName);
    }

    /**
     * This method will receive generated source and class files.
     */
    @Override
    public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind,
        FileObject sibling) throws IOException {
      String path = BinaryName.toInternalName(className);
      String suffix;
      switch (kind) {
        case CLASS:
          suffix = ".class";
          break;
        case SOURCE:
          suffix = ".java";
          break;
        default:
          throw new UnsupportedOperationException("Unexpected kind " + kind);
      }
      MemoryJavaFileObject toReturn =
          new MemoryJavaFileObject(uri("memory:///" + path + suffix), kind);
      if (StandardLocation.CLASS_OUTPUT.equals(location) && Kind.CLASS.equals(kind)) {
        toOutput.add(toReturn);
      }
      return toReturn;
    }

    @Override
    public boolean isSameFile(FileObject a, FileObject b) {
      if (a instanceof MemoryJavaFileObject && b instanceof MemoryJavaFileObject) {
        MemoryJavaFileObject memoryA = (MemoryJavaFileObject) a;
        MemoryJavaFileObject memoryB = (MemoryJavaFileObject) b;
        return memoryA.getKind().equals(memoryB.getKind())
            && memoryA.toUri().equals(memoryB.toUri());
      }
      if (a instanceof FakeJavaFileObject && b instanceof FakeJavaFileObject) {
        // Only one file ever created
        return true;
      }
      return super.isSameFile(a, b);
    }

    private void writeToDirectory() throws IOException {
      for (MemoryJavaFileObject file : toOutput) {
        String path = file.toUri().getPath();
        if (path.equals("/fake/Fake.class")) {
          // ignore dummy class
          continue;
        }
        File target = new File(output, path);
        target.getParentFile().mkdirs();
        FileOutputStream out = new FileOutputStream(target);
        out.write(file.bytes.toByteArray());
        out.close();
      }
    }

    private void writeToJar() throws IOException, FileNotFoundException {
      JarOutputStream jar = new JarOutputStream(new FileOutputStream(output));
      for (MemoryJavaFileObject file : toOutput) {
        String path = file.toUri().getPath();
        if (path.equals("/fake/Fake.class")) {
          // ignore dummy class
          continue;
        }
        // Strip leading /
        ZipEntry entry = new ZipEntry(path.substring(1));
        jar.putNextEntry(entry);
        jar.write(file.bytes.toByteArray());
      }
      jar.close();
    }
  }

  /**
   * Provides a fake type to seed the compilation process with.
   */
  private static class FakeJavaFileObject extends SimpleJavaFileObject {
    public FakeJavaFileObject() {
      super(uri("fake:///fake/Fake.java"), JavaFileObject.Kind.SOURCE);
    }

    @Override
    public CharSequence getCharContent(boolean arg0) throws IOException {
      return "package fake; interface Fake {}";
    }
  }

  /**
   * An in-memory implementation of JavaFileObject.
   */
  private static class MemoryJavaFileObject extends SimpleJavaFileObject {
    private ByteArrayOutputStream bytes;
    private StringWriter charContents;

    public MemoryJavaFileObject(URI uri, JavaFileObject.Kind kind) {
      super(uri, kind);
    }

    @Override
    public CharSequence getCharContent(boolean ignored) throws IOException {
      return charContents.toString();
    }

    @Override
    public OutputStream openOutputStream() throws IOException {
      bytes = new ByteArrayOutputStream();
      return bytes;
    }

    @Override
    public Writer openWriter() throws IOException {
      charContents = new StringWriter();
      return charContents;
    }
  }

  public static void main(String[] args) throws IOException {
    System.exit(exec(args) ? 0 : -1);
  }

  /**
   * A testable "main" method.
   */
  public static boolean exec(String[] args) throws IOException {
    return exec(args, ToolProvider.getSystemJavaCompiler());
  }

  public static boolean exec(String[] args, JavaCompiler compiler) throws IOException {
    if (args.length < 2) {
      System.err.println("java -cp requestfactory-client.jar:your_server-code.jar "
          + ValidationTool.class.getCanonicalName()
          + " (/some/directory | output.jar) com.example.shared.MyRequestFactory");
      System.err.println("See "
          + "http://code.google.com/p/google-web-toolkit/wiki/RequestFactoryInterfaceValidation "
          + "for more information.");
      return false;
    }
    if (compiler == null) {
      System.err.println("This tool must be run with a JDK, not a JRE");
      return false;
    }
    if (!compiler.getSourceVersions().contains(SourceVersion.RELEASE_6)) {
      System.err.println("This tool must be run with a Java 1.6 compiler");
      return false;
    }

    boolean clientOnly = false;
    List<String> argList = new ArrayList<String>(Arrays.asList(args));
    if (argList.get(0).equals("-client")) {
      clientOnly = true;
      argList.remove(0);
    }

    // Control how the compile process writes data to disk
    JavaFileManager fileManager =
        new JarOrDirectoryOutputFileManager(new File(argList.remove(0)), compiler
            .getStandardFileManager(null, null, null));

    // Create a validator and require it to process the specified types
    RfValidator processor = new RfValidator();
    if (clientOnly) {
      processor.setClientOnly(true);
    } else {
      processor.setMustResolveAllMappings(true);
    }
    processor.setRootOverride(argList);

    // Create the compilation task
    CompilationTask task =
        compiler.getTask(null, fileManager, null, null, null, Arrays
            .asList(new FakeJavaFileObject()));
    task.setProcessors(Arrays.asList(processor));
    if (!task.call()) {
      return false;
    }
    // Save data only on successful compilation
    fileManager.close();
    return true;
  }

  /**
   * Convenience method for discarding {@link URISyntaxException}.
   */
  private static URI uri(String contents) {
    try {
      return new URI(contents);
    } catch (URISyntaxException e) {
      throw new RuntimeException(e);
    }
  }
}
