/*
 * 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.geode.test.compiler;

import static java.util.stream.Collectors.toList;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import javax.tools.ToolProvider;

import com.google.common.base.Charsets;
import com.google.common.io.Files;
import org.apache.commons.io.FileUtils;


public class JavaCompiler {
  private File tempDir;
  private String classpath;

  public JavaCompiler() {
    this.tempDir = Files.createTempDir();
    tempDir.deleteOnExit();
    this.classpath = System.getProperty("java.class.path");
  }

  public void addToClasspath(File jarFile) {
    classpath += File.pathSeparator + jarFile.getAbsolutePath();
  }

  public List<CompiledSourceCode> compile(File... sourceFiles) throws IOException {
    String[] sourceFileContents =
        Arrays.stream(sourceFiles).map(this::readFileToString).toArray(String[]::new);

    return compile(sourceFileContents);
  }

  public List<CompiledSourceCode> compile(String... sourceFileContents) throws IOException {
    UncompiledSourceCode[] uncompiledSourceCodes = Arrays.stream(sourceFileContents)
        .map(UncompiledSourceCode::fromSourceCode).toArray(UncompiledSourceCode[]::new);

    return compile(uncompiledSourceCodes);
  }

  public List<CompiledSourceCode> compile(UncompiledSourceCode... uncompiledSources)
      throws IOException {
    File temporarySourcesDirectory = createSubdirectory(tempDir, "sources");
    File temporaryClassesDirectory = createSubdirectory(tempDir, "classes");

    List<String> options =
        Stream.of("-d", temporaryClassesDirectory.getAbsolutePath(), "-classpath", classpath)
            .collect(toList());

    try {
      for (UncompiledSourceCode sourceCode : uncompiledSources) {
        File sourceFile = new File(temporarySourcesDirectory, sourceCode.simpleClassName + ".java");
        FileUtils.writeStringToFile(sourceFile, sourceCode.sourceCode, Charsets.UTF_8);
        options.add(sourceFile.getAbsolutePath());
      }

      int exitCode = ToolProvider.getSystemJavaCompiler().run(System.in, System.out, System.err,
          options.toArray(new String[] {}));

      if (exitCode != 0) {
        throw new RuntimeException(
            "Unable to compile the given source code. See System.err for details.");
      }

      List<CompiledSourceCode> compiledSourceCodes = new ArrayList<>();
      addCompiledClasses(compiledSourceCodes, "", temporaryClassesDirectory);
      return compiledSourceCodes;
    } finally {
      FileUtils.deleteDirectory(temporaryClassesDirectory);
    }
  }

  private static void addCompiledClasses(List<CompiledSourceCode> ret, String pkgName, File dir)
      throws IOException {
    for (File file : dir.listFiles()) {
      String filename = file.getName();

      if (file.isDirectory()) {
        String qname = pkgName + filename + ".";
        addCompiledClasses(ret, qname, file);
      } else if (filename.endsWith(".class")) {
        String qname = pkgName + filename.substring(0, filename.length() - 6);
        ret.add(new CompiledSourceCode(qname, FileUtils.readFileToByteArray(file)));
      } else {
        System.err.println("Unexpected file : " + file.getAbsolutePath());
      }
    }
  }

  private File createSubdirectory(File parent, String directoryName) {
    File subdirectory = parent.toPath().resolve(directoryName).toFile();
    if (!subdirectory.exists()) {
      subdirectory.mkdirs();
    }

    if (!subdirectory.exists() || !subdirectory.isDirectory()) {
      throw new IllegalArgumentException("Invalid directory" + subdirectory.getAbsolutePath());
    }

    return subdirectory;
  }

  private String readFileToString(File file) {
    try {
      return FileUtils.readFileToString(file, Charsets.UTF_8);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
}
