/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.drill.exec.compile;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;

import org.apache.drill.common.config.DrillConfig;
import org.apache.drill.common.util.DrillStringUtils;
import org.apache.drill.exec.compile.ClassTransformer.ClassNames;
import org.apache.drill.exec.exception.ClassTransformationException;
import org.apache.drill.exec.expr.CodeGenerator;
import org.apache.drill.exec.server.options.OptionSet;
import org.codehaus.commons.compiler.CompileException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Implements the "plain Java" method of code generation and
 * compilation. Given a {@link CodeGenerator}, obtains the generated
 * source code, compiles it with the selected compiler, loads the
 * byte-codes into a class loader and provides the resulting
 * class. Compared with the {@link ClassTransformer} mechanism,
 * this one requires the code generator to have generated a complete
 * Java class that is capable of direct compilation and loading.
 * This means the generated class must be a subclass of the template
 * so that the JVM can use normal Java inheritance to associate the
 * template and generated methods.
 * <p>
 * Here is how to use the plain Java technique to debug
 * generated code:
 * <ul>
 * <li>Set the config option <tt>drill.exec.compile.code_dir</tt>
 * to the location where you want to save the generated source
 * code.</li>
 * <li>Where you generate code (using a {@link CodeGenerator}),
 * set the "plain Java" options:<pre>
 * CodeGenerator&lt;Foo> cg = ...
 * cg.plainJavaCapable(true); // Class supports plain Java
 * cg.preferPlainJava(true); // Actually generate plain Java
 * cg.saveCodeForDebugging(true); // Save code for debugging
 * ...</pre>
 * Note that <tt>saveCodeForDebugging</tt> automatically sets the PJ
 * option if the generator is capable. Call <tt>preferPlainJava</tt>
 * only if you want to try PJ for this particular generated class
 * without saving the generated code.</li>
 * <li>In your favorite IDE, add to the code lookup path the
 * code directory saved earlier. In Eclipse, for example, you do
 * this in the debug configuration you will use to debug Drill.</li>
 * <li>Set a breakpoint in template used for the generated code.</li>
 * <li>Run Drill. The IDE will stop at your breakpoint.</li>
 * <li>Step into the generated code. Examine class field and
 * local variables. Have fun!</li>
 * </ul>
 * <p>
 * Most generated classes have been upgraded to support Plain Java
 * compilation. Once this work is complete, the calls to
 * <tt>plainJavaCapable<tt> can be removed as all generated classes
 * will be capable.
 * <p>
 * The setting to prefer plain Java is ignored for any remaining generated
 * classes not marked as plain Java capable.
 */
public class ClassBuilder {

  private static final Logger logger = LoggerFactory.getLogger(ClassBuilder.class);
  public static final String CODE_DIR_OPTION = CodeCompiler.COMPILE_BASE + ".code_dir";

  private final DrillConfig config;
  private final OptionSet options;
  private final File codeDir;

  public ClassBuilder(DrillConfig config, OptionSet optionManager) {
    this.config = config;
    options = optionManager;

    // Code can be saved per-class to enable debugging.
    // Just request the code generator to persist code,
    // point your debugger to the directory set below, and you
    // can step into the code for debugging. Code is not saved
    // be default because doing so is expensive and unnecessary.
    codeDir = new File(config.getString(CODE_DIR_OPTION));
  }

  /**
   * Given a code generator which has already generated plain Java
   * code, compile the code, create a class loader, and return the
   * resulting Java class.
   *
   * @param cg a plain Java capable code generator that has generated
   * plain Java code
   * @return the class that the code generator defines
   * @throws ClassTransformationException
   */
  public Class<?> getImplementationClass(CodeGenerator<?> cg) throws ClassTransformationException {
    try {
      return compileClass(cg);
    } catch (CompileException | ClassNotFoundException|IOException e) {
      throw new ClassTransformationException(e);
    }
  }

  /**
   * Performs the actual work of compiling the code and loading the class.
   *
   * @param cg the code generator that has built the class(es) to be generated.
   * @return the class, after code generation and (if needed) compilation.
   * @throws IOException if an error occurs when optionally writing code to disk.
   * @throws CompileException if the generated code has compile issues.
   * @throws ClassNotFoundException if the generated code references unknown classes.
   * @throws ClassTransformationException generic "something is wrong" error from
   * Drill class compilation code.
   */
  private Class<?> compileClass(CodeGenerator<?> cg) throws IOException, CompileException, ClassNotFoundException, ClassTransformationException {
    final long t1 = System.nanoTime();

    // Get the plain Java code.
    String code = cg.getGeneratedCode();

    // Get the class names (dotted, file path, etc.)
    String className = cg.getMaterializedClassName();
    ClassTransformer.ClassNames name = new ClassTransformer.ClassNames(className);

    // A key advantage of this method is that the code can be
    // saved and debugged, if needed.
    if (cg.isCodeToBeSaved()) {
      saveCode(code, name);
    }

    // Compile the code and load it into a class loader.
    CachedClassLoader classLoader = new CachedClassLoader();
    ClassCompilerSelector compilerSelector = new ClassCompilerSelector(classLoader, config, options);
    Map<String,byte[]> results = compilerSelector.compile(name, code);
    classLoader.addClasses(results);

    long totalBytecodeSize = 0;
    for (byte[] clazz : results.values()) {
      totalBytecodeSize += clazz.length;
    }
    logger.debug("Compiled {}: bytecode size = {}, time = {} ms.",
                 cg.getClassName(),
                  DrillStringUtils.readable(totalBytecodeSize),
                  (System.nanoTime() - t1 + 500_000) / 1_000_000);

    // Get the class from the class loader.
    try {
      return classLoader.findClass(className);
    } catch (ClassNotFoundException e) {
      // This should never occur.
      throw new IllegalStateException("Code load failed", e);
    }
  }

  /**
   * Save code to a predefined location for debugging. To use the code
   * for debugging, make sure the save location is on your IDE's source
   * code search path. Code is saved in usual Java format with each
   * package as a directory. The provided code directory becomes a
   * source directory, as in Maven's "src/main/java".
   *
   * @param code the source code
   * @param name the class name
   */
  private void saveCode(String code, ClassNames name) {

    String pathName = name.slash + ".java";
    File codeFile = new File(codeDir, pathName);
    codeFile.getParentFile().mkdirs();
    try (final FileWriter writer = new FileWriter(codeFile)) {
      writer.write(code);
    } catch (IOException e) {
      System.err.println("Could not save: " + codeFile.getAbsolutePath());
    }
  }
}
