/*
 * Copyright (c) Robert Bosch GmbH. All rights reserved.
 */
package org.eclipse.blockchain.core;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.apache.commons.io.FileUtils;
import org.eclipse.blockchain.core.log.EthereumLogService;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.osgi.internal.loader.EquinoxClassLoader;
import org.eclipse.osgi.internal.loader.classpath.ClasspathEntry;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Display;
import org.osgi.framework.Bundle;

import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * Code inside this class is just a prototype so it could contain duplicate/in-efficient code and maybe unwanted code
 * SOLDITY COMPILATION IS TESTED WITH SOLC-0.5.4 version as of NOW
 *
 * @author ADG5COB
 */
public class CoreCommandExecutor {


  private Process gethServer = null;

  /**
   * As of now only one Geth server instance is considered so everything related to geth is maintained as member
   * variables
   */
  private String gethIPC = "";
  private String gethDataDirectory = "";
  private Map<String, String> gethOptions = null;
  private final String solcCommand = "solc-path solidity-file --bin --abi --optimize -o output-directory";
  private final String web3jCommand =
      "web3j-path solidity generate -a=abi-path -b=bin-path -o=output-directory -p=com.bosch";

  private final Map<String, SolidityABI[]> solidityABIMap = new HashMap<>();
  private static CoreCommandExecutor instance;
  private String gethServerStartError = "";

  /**
   * This instance is used to handle functionality related to geth and solidity
   *
   * @return - CorecommandExecutor instance
   */
  public static CoreCommandExecutor getInstance() {
    if (instance == null) {
      instance = new CoreCommandExecutor();
    }
    return instance;
  }

  String getGethServerStartError() {
    return this.gethServerStartError;
  }

  /**
   * To start/stop mining process
   *
   * @param start - if true mining will start/ if false mining will stop
   * @throws IOException -
   * @throws InterruptedException -
   */
  public void mine(final boolean start) throws IOException, InterruptedException {
    Process miner = Runtime.getRuntime().exec("cmd");
    StringJoiner inputStream = new StringJoiner(System.lineSeparator());
    StringJoiner errorStream = new StringJoiner(System.lineSeparator());
    cmdRead(miner, inputStream);
    cmdReadError(miner, errorStream);

    PrintWriter writer = new PrintWriter(miner.getOutputStream());
    if (start) {
      writer.println("geth attach " + this.gethIPC.replace("\\\\", "\\"));
      writer.println("miner.start(3)");
      writer.close();
      miner.waitFor();
      miner.destroy();
    }
    else {
      writer.println("geth attach " + this.gethIPC.replace("\\\\", "\\"));
      writer.println("miner.stop()");
      writer.close();
      miner.waitFor();
      miner.destroy();
    }
  }

  private void transferArtifactsFromTempToOutput(final String tempLocation, final String outputLocation,
      final String solName)
      throws IOException {
    // ABI file
    File abiTempFile = new File(tempLocation + File.separator + solName + ".abi");
    File abiFile = new File(outputLocation + File.separator + solName + ".abi");
    abiFile.createNewFile();
    FileUtils.copyFile(abiTempFile, abiFile);

    // BIN file
    File binTempFile = new File(tempLocation + File.separator + solName + ".bin");
    File binFile = new File(outputLocation + File.separator + solName + ".bin");
    abiFile.createNewFile();
    FileUtils.copyFile(binTempFile, binFile);
  }

  /**
   * Some osgi internal API are accessed in this method to retrieve the classpath content of this plugin. It won't be
   * changed until problems pop-up
   *
   * @param projectName -
   * @param solidityFiles -
   * @param outputDir -
   * @return -
   * @throws IOException -
   * @throws InterruptedException -
   * @throws ClassNotFoundException -
   */
  public String solidityCompile(final String projectName, final List<IResource> solidityFiles,
      final IResource outputDir)
      throws IOException, InterruptedException, ClassNotFoundException {
    String solcCompilerPath = InstanceScope.INSTANCE.getNode(SolidityPreferenceConstants.PREF_NODE)
        .get(SolidityPreferenceConstants.PREF_KEY, "");
    if (solcCompilerPath.isEmpty()) {
      return "Compiler is not set... Please set it in solidity preference page";
    }
    for (IResource solFile : solidityFiles) {
      String tempLocation = outputDir.getLocation().toOSString() + File.separator + "temp";
      File tempOutputDir = new File(tempLocation);
      if (tempOutputDir.exists() && tempOutputDir.isDirectory()) {
        tempOutputDir.delete();
      }
      tempOutputDir.mkdir();

      String compileCommand =
          this.solcCommand.replace("solc-path", getCmdLinePath(solcCompilerPath + File.separator + "solc"))
              .replace("solidity-file", getCmdLinePath(solFile.getLocation().toOSString()))
              .replace("output-directory", getCmdLinePath(tempOutputDir.getAbsolutePath()));

      Process solcExe = Runtime.getRuntime().exec("cmd");
      StringJoiner inputStream = new StringJoiner(System.lineSeparator());
      StringJoiner errorStream = new StringJoiner(System.lineSeparator());

      cmdRead(solcExe, inputStream);
      cmdReadError(solcExe, errorStream);

      PrintWriter writer = new PrintWriter(solcExe.getOutputStream());
      writer.println(compileCommand);
      writer.close();

      solcExe.waitFor();
      solcExe.destroy();
      if (inputStream.toString().contains("Error") || errorStream.toString().contains("Error")) {
        return "Some errors occurred during compilation please check the console!!!";
      }
      transferArtifactsFromTempToOutput(tempOutputDir.getAbsolutePath(), outputDir.getLocation().toOSString(),
          solFile.getName().replace(".sol", ""));
      // Reading abi json
      storeABIinSolidityMap(
          outputDir.getLocation().toOSString() + File.separator + solFile.getName().replace(".sol", ".abi"),
          solFile.getLocation().toOSString());

      // Solidity ABI javaType update
      CoreCommandExecutor.getInstance().updateSolABIMap(solFile.getLocation().toOSString(), updateSolJavaTypes(
          projectName, CoreCommandExecutor.getInstance().getSolABIMap(solFile.getLocation().toOSString())));

      // Java Wrapper Creation
      String web3jCmd = this.web3jCommand
          .replace("web3j-path", getCmdLinePath(unzipAndGetWeb3jPath()) + File.separator + "web3j")
          .replace("abi-path",
              getCmdLinePath(
                  outputDir.getLocation().toOSString() + File.separator + solFile.getName().replace(".sol", ".abi")))
          .replace("bin-path",
              getCmdLinePath(
                  outputDir.getLocation().toOSString() + File.separator + solFile.getName().replace(".sol", ".bin")))
          .replace("output-directory", getCmdLinePath(outputDir.getLocation().toOSString()));
      EthereumLogService.INSTANCE.log("web3j command -> " + web3jCmd);
      Process web3jExe = Runtime.getRuntime().exec("cmd");

      cmdRead(web3jExe, inputStream);
      cmdReadError(web3jExe, errorStream);

      writer = new PrintWriter(web3jExe.getOutputStream());

      writer.println("set JAVA_HOME=" + getJDKPath());

      writer.println(web3jCmd);

      ClassLoader classLoader = CoreCommandExecutor.class.getClassLoader();
      ClasspathEntry[] hostClasspathEntries =
          ((EquinoxClassLoader) classLoader).getClasspathManager().getHostClasspathEntries();
      String cp = "";
      for (ClasspathEntry c : hostClasspathEntries) {
        cp = cp + c.getBundleFile().getBaseFile().toString() + ";";
      }

      writer
          .println(
              "javac " +
                  getCmdLinePath(outputDir.getLocation().toOSString() + File.separator + "com" + File.separator +
                      "bosch" + File.separator + solFile.getName().replace(".sol", ".java")) +
                  " -cp " + getCmdLinePath(cp));
      writer.close();

      web3jExe.waitFor();
      web3jExe.destroy();

      ProjectCreator.getInstance().getEthProject(projectName).addCompiledSolidityFiles(solFile);
      FileUtils.deleteDirectory(tempOutputDir);
    }


    return "";
  }

  private String getCmdLinePath(final String path) {
    return "\"" + path + "\"";
  }

  private SolidityABI[] updateSolJavaTypes(final String projectName, final SolidityABI[] solABI)
      throws ClassNotFoundException, IOException, InterruptedException {
    SolidityABI[] updatedSolABI = new SolidityABI[solABI.length];
    for (int i = 0; i < solABI.length; i++) {
      updatedSolABI[i] = solABI[i];
      if (updatedSolABI[i].getInputs() != null) {
        for (IOABI ioa : updatedSolABI[i].getInputs()) {
          SolidityDynamicValueCasterHandler.assignJavaType(projectName,
              SolidityToJavaDataTypeResolver.getInstance().getJavaType(ioa.getType(), ioa), ioa);
        }
      }
      if (updatedSolABI[i].getOutputs() != null) {
        for (IOABI ioa : updatedSolABI[i].getOutputs()) {
          SolidityDynamicValueCasterHandler.assignJavaType(projectName,
              SolidityToJavaDataTypeResolver.getInstance().getJavaType(ioa.getType(), ioa), ioa);
        }
      }
    }

    return updatedSolABI;
  }

  private String unzipAndGetWeb3jPath() throws IOException {
    Bundle bundle = Platform.getBundle("org.eclipse.blockchain.core");
    return unzipWeb3jZip(FileLocator.toFileURL(bundle.getEntry("res/web3j-4.3.0.zip")).getPath());
  }

  private String unzipWeb3jZip(final String zipPath) throws IOException {
    ZipFile web3jZip = new ZipFile(zipPath);
    String destinationDir = ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString();
    File web3jZipContainer = new File(destinationDir + File.separator + "web3jContainer");
    if (!web3jZipContainer.exists()) {
      web3jZipContainer.mkdir();
      final byte[] buf = new byte[4096];
      final Enumeration<? extends ZipEntry> zipEnum = web3jZip.entries();
      while (zipEnum.hasMoreElements()) {
        final ZipEntry item = zipEnum.nextElement();

        if (item.isDirectory()) {
          final File newdir = new File(web3jZipContainer + File.separator + item.getName());
          newdir.mkdir();
        }
        else {
          final String newfilePath = web3jZipContainer + File.separator + item.getName();
          final File newFile = new File(newfilePath);
          if (!newFile.getParentFile().exists()) {
            newFile.getParentFile().mkdirs();
          }
          try (InputStream is = web3jZip.getInputStream(item);
              FileOutputStream fos = new FileOutputStream(newfilePath);) {

            int len;
            while ((len = is.read(buf)) > 0) {
              fos.write(buf, 0, len);
            }
            is.close();
            fos.close();
          }
        }
      }
    }
    web3jZip.close();

    return web3jZipContainer.getAbsolutePath() + File.separator + "web3j-4.3.0" + File.separator + "bin";
  }

  /**
   * @return -
   * @throws IOException -
   * @throws InterruptedException -
   */
  public String getJDKPath() throws IOException, InterruptedException {
    String jdkPath = "";
    Process process = Runtime.getRuntime().exec("cmd");
    PrintWriter writer = new PrintWriter(process.getOutputStream());

    StringJoiner readJDKPath = new StringJoiner(System.lineSeparator());
    cmdRead(process, readJDKPath);

    writer.println("where javac");
    writer.close();

    process.waitFor();
    process.destroy();

    String[] lines = readJDKPath.toString().split(System.lineSeparator());
    for (String line : lines) {
      if (line.contains("javac.exe")) {
        jdkPath = line.replace("\\bin\\javac.exe", "").replace("\\", "\\\\");
        break;
      }
    }

    return getCmdLinePath(jdkPath);
  }

  private void storeABIinSolidityMap(final String abiPath, final String solidityFilePath) throws IOException {
    String abiJson = readABI(abiPath);
    ObjectMapper jsonMapper = new ObjectMapper();
    SolidityABI[] readValue = jsonMapper.readValue(abiJson, SolidityABI[].class);
    for (SolidityABI sabi : readValue) {
      if (sabi.isPayable()) {
        IOABI[] inputs = sabi.getInputs();
        IOABI[] newInputs = new IOABI[inputs.length + 1];
        for (int o = 0; o < inputs.length; o++) {
          newInputs[o] = inputs[o];
        }
        IOABI payableInput = new IOABI();
        payableInput.setName("payableAmount");
        payableInput.setType("uint256");
        newInputs[inputs.length] = payableInput;
        sabi.setInputs(newInputs);
      }
    }
    this.solidityABIMap.put(solidityFilePath, readValue);
  }


  /**
   * @param solPath - The absolute path of solidity file
   * @param onlyConstructor - If true will return only constructor ui components
   * @return - The UI content to be constructed in transactions view
   */
  public Map<String, String> getUIComponentForSolidityFile(final String solPath, final boolean onlyConstructor) {
    SolidityABI[] solABi = this.solidityABIMap.get(solPath);

    Map<String, String> uiMap = new HashMap<>();
    if (solABi != null) {
      for (SolidityABI sABI : solABi) {
        if (sABI.getType().equalsIgnoreCase("constructor")) {
          if (onlyConstructor) {
            String key = "deploy";
            IOABI[] inputs = sABI.getInputs();
            String value = constructUIValue(inputs);
            uiMap.put(key, value);
          }
        }
        else if (sABI.getType().equalsIgnoreCase("function")) {
          if (!onlyConstructor) {
            String key = sABI.getName();
            IOABI[] inputs = sABI.getInputs();
            String value = constructUIValue(inputs);
            uiMap.put(key + "-" + value, value);
          }
        }
      }
    }

    return uiMap;
  }

  private String constructUIValue(final IOABI[] inputs) {
    StringJoiner uiElemString = new StringJoiner(";");
    for (IOABI input : inputs) {
      uiElemString.add(input.getJavaType().getSimpleName());
    }
    return uiElemString.toString();
  }

  /**
   * @param abiPath -
   * @return -
   */
  public SolidityABI[] getSolABIMap(final String abiPath) {
    return this.solidityABIMap.get(abiPath);
  }

  /**
   * @param abiPath -
   * @param updatedSolABI -
   */
  public void updateSolABIMap(final String abiPath, final SolidityABI[] updatedSolABI) {
    this.solidityABIMap.put(abiPath, updatedSolABI);
  }

  private String readABI(final String abiPath) throws IOException {
    StringJoiner sj = new StringJoiner("");
    try (BufferedReader br = new BufferedReader(new FileReader(new File(abiPath)))) {
      String line = "";
      while ((line = br.readLine()) != null) {
        sj.add(line);
      }
    }
    return sj.toString();
  }

  /**
   * @return -
   * @throws IOException -
   * @throws InterruptedException -
   */
  public String isGethInstalled() throws IOException, InterruptedException {
    /**
     * This is not fully constructed but this should be first step check when someone tries to invoke ethereum project
     * creation
     */
    StringJoiner inputStream = new StringJoiner(System.lineSeparator());
    StringJoiner errorStream = new StringJoiner(System.lineSeparator());
    String gethCheck = "";
    Process gethProcess = Runtime.getRuntime().exec("cmd");
    cmdRead(gethProcess, inputStream);
    cmdReadError(gethProcess, errorStream);

    PrintWriter processWriter = new PrintWriter(gethProcess.getOutputStream());
    processWriter.println("geth version");
    processWriter.close();

    gethProcess.waitFor();
    gethCheck = errorStream.toString();
    gethProcess.destroy();
    return gethCheck;
  }

  /**
   * @param dataDir -
   * @param initFilePath -
   * @param localGethOptions -
   * @return - Return if any error occurs during server start
   * @throws IOException -
   * @throws InterruptedException
   */
  public String startGethServer(final String dataDir, final String initFilePath,
      final Map<String, String> localGethOptions)
      throws IOException, InterruptedException {
    if (isGethInstalled()
        .equals(NLS.bind(CoreCommandMessages.FRAMEWORK_NOT_INSTALLED, "'geth'", System.lineSeparator()))) {
      return "Either Geth is not installed (or) its reference is not set in PATH env variable";
    }
    this.gethServerStartError = "Geth";
    StringJoiner inputStream = new StringJoiner(System.lineSeparator());
    StringJoiner errorStream = new StringJoiner(System.lineSeparator());
    this.gethDataDirectory = dataDir;
    CoreCommandExecutor.getInstance().gethOptions = localGethOptions;
    this.gethServer = Runtime.getRuntime().exec("cmd.exe");
    cmdRead(this.gethServer, inputStream);
    cmdReadError(this.gethServer, errorStream);

    String initFile = initFilePath;
    String genesisFilePath = dataDir + File.separator + "genesis.json";
    if (new File(genesisFilePath).exists()) {
      initFile = genesisFilePath;
    }
    else {
      if (initFilePath.isEmpty()) {
        initFile = createGethInitFile(dataDir);
      }
    }
    startGethServerLocal(dataDir, initFile, localGethOptions);
    return "";
  }

  private void startGethServerLocal(final String dataDir, final String initFile,
      final Map<String, String> localGethOptions) {
    PrintWriter processWriter = new PrintWriter(this.gethServer.getOutputStream());
    if (!initFile.isEmpty() && !new File(dataDir + File.separator + "geth").exists()) {
      processWriter.println("geth --datadir " + getCmdLinePath(dataDir) + " init " + getCmdLinePath(initFile) + "");
    }
    String args = constructGethArguments(localGethOptions);
    processWriter.println("geth --datadir " + getCmdLinePath(dataDir) + " " + args);
    processWriter.close();
    /**
     * This below code is required because geth once started won't terminate and it should not terminate because its a
     * server
     */
    Display.getDefault().syncExec(() -> {
      new Thread(() -> {
        try {
          this.gethServer.waitFor();
        }
        catch (InterruptedException e) {
          BlockchainCore.getInstance().logException("", e.getMessage(), e);
        }
      }, "Geth Server").start();
    });
  }

  /**
   * @return - True if geth is started/ false otherwise
   */
  public boolean isGethStarted() {
    return (this.gethServer != null) && this.gethServer.isAlive() && !this.gethIPC.isEmpty();
  }

  /**
   * @return - The geth server data directory
   */
  public String getDataDir() {
    return this.gethDataDirectory;
  }

  /**
   * @return -The geth command line options
   */
  public Map<String, String> getGethOptions() {
    return this.gethOptions;
  }

  /**
   * @return - Returns the default network id
   */
  public String getDefaultNetworkIdForGeth() {
    String defaultNetworkId = "";
    try (BufferedReader br =
        new BufferedReader(new InputStreamReader(CoreCommandExecutor.class.getResourceAsStream("genesis.template")));) {
      String genesisContent = "";
      while ((genesisContent = br.readLine()) != null) {
        if (genesisContent.contains("chainId")) {
          defaultNetworkId = genesisContent.substring(genesisContent.indexOf(':') + 1).replace(",", "").trim();
        }
      }
    }
    catch (IOException e) {
      BlockchainCore.getInstance().logException("", e.getMessage(), e);
    }
    return defaultNetworkId;
  }

  private String constructGethArguments(final Map<String, String> localGethOptions) {
    StringJoiner arguments = new StringJoiner(" ");
    localGethOptions.forEach((k, v) -> arguments.add("--" + k + "" + (v.isEmpty() ? "" : " " + v)));
    return arguments.toString();
  }

  /**
   * Terminate geth server
   */
  public void terminateGethServer() {
    if (CoreCommandExecutor.getInstance().gethServer != null) {
      this.gethIPC = "";
      this.gethServer.destroyForcibly();
      try {
        Process terminator = Runtime.getRuntime().exec("cmd.exe");
        PrintWriter pw = new PrintWriter(terminator.getOutputStream());
        pw.println("taskkill /F /IM geth.exe");
        pw.close();

        terminator.waitFor();
        terminator.destroy();
      }
      catch (IOException | InterruptedException e) {
        BlockchainCore.getInstance().logException("", e.getMessage(), e);
      }
    }
  }

  private String createGethInitFile(final String dataDir) throws IOException {
    File gethInitFile = new File(dataDir + File.separator + "genesis.json");
    gethInitFile.createNewFile();// NOSONAR

    try (
        BufferedReader br = new BufferedReader(
            new InputStreamReader(CoreCommandExecutor.class.getResourceAsStream("genesis.template")));
        BufferedWriter bw = new BufferedWriter(new FileWriter(gethInitFile));) {
      String genesisContent = "";
      while ((genesisContent = br.readLine()) != null) {
        bw.append(genesisContent);
        bw.append(System.lineSeparator());
      }
    }
    return gethInitFile.getAbsolutePath();
  }


  /**
   * Read output stream of process going to be executed
   *
   * @param process - The process that is going to start
   * @param inputStream - A log recording object
   */
  public void cmdRead(final Process process, final StringJoiner inputStream) {
    Thread processReadThread = new Thread(() -> {
      String line = "";
      try (BufferedReader processReader = new BufferedReader(new InputStreamReader(process.getInputStream()));) {
        while ((line = processReader.readLine()) != null) {
          inputStream.add(line.trim());
          if (line.contains("Error") && this.gethServerStartError.equals("Geth")) {
            this.gethServerStartError = line;
          }
          if (line.contains("IPC endpoint opened")) {// To determine IPC endpoint when geth server is started.
            this.gethIPC = line.substring(line.indexOf("url=") + 4);
          }
          EthereumLogService.INSTANCE.log(line);
          System.err.println(line);
        }
      }
      catch (IOException e) {
        BlockchainCore.getInstance().logException("", e.getMessage(), e);
      }
    }, "Process Read Thread");
    processReadThread.start();
  }

  /**
   * @return - the geth socket handle
   */
  public String getIPCPath() {
    return this.gethIPC;
  }

  /**
   * Read error stream of process going to be executed
   *
   * @param process - The process that is going to start
   * @param errorStream - A log recording object
   */
  public void cmdReadError(final Process process, final StringJoiner errorStream) {
    Thread processErrorThread = new Thread(() -> {
      String line = "";
      try (BufferedReader processReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));) {
        while ((line = processReader.readLine()) != null) {
          errorStream.add(line.trim());
          if (line.contains("Error") && this.gethServerStartError.equals("Geth")) {
            this.gethServerStartError = line;
          }
          if (line.contains("IPC endpoint opened")) {// To determine IPC endpoint when geth server is started.
            this.gethIPC = line.substring(line.indexOf("url=") + 4);
          }
          EthereumLogService.INSTANCE.errorLog(line);
          System.err.println(line);
        }
      }
      catch (IOException e) {
        BlockchainCore.getInstance().logException("", e.getMessage(), e);
      }
    }, "Process Error Thread");
    processErrorThread.start();
  }
}
