package org.jetbrains.plugins.terminal;

import com.intellij.execution.TaskExecutor;
import com.intellij.execution.configurations.EncodingEnvironmentUtil;
import com.intellij.execution.process.*;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import com.intellij.util.containers.HashMap;
import com.jediterm.pty.PtyProcessTtyConnector;
import com.jediterm.terminal.TtyConnector;
import com.pty4j.PtyProcess;
import com.pty4j.util.PtyUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * @author traff
 */
public class LocalTerminalDirectRunner extends AbstractTerminalRunner<PtyProcess> {
  private static final Logger LOG = Logger.getInstance(LocalTerminalDirectRunner.class);

  private final Charset myDefaultCharset;

  public LocalTerminalDirectRunner(Project project) {
    super(project);
    myDefaultCharset = Charset.forName("UTF-8");
  }

  private static boolean hasLoginArgument(String name) {
    return name.equals("bash") || name.equals("sh") || name.equals("zsh");
  }

  private static String getShellName(String path) {
    return new File(path).getName();
  }

  private static File findRCFile() {
    try {
      final String folder = PtyUtil.getPtyLibFolderPath();
      if (folder != null) {
        File rcFile = new File(folder, "jediterm.in");
        if (rcFile.exists()) {
          return rcFile;
        }
      }
    }
    catch (Exception e) {
      LOG.warn("Unable to get JAR folder", e);
    }
    return null;
  }

  @NotNull
  public static LocalTerminalDirectRunner createTerminalRunner(Project project) {
    return new LocalTerminalDirectRunner(project);
  }

  @Override
  protected PtyProcess createProcess(@Nullable String directory) throws ExecutionException {
    Map<String, String> envs = new HashMap<String, String>(System.getenv());
    envs.put("TERM", "xterm-256color");
    EncodingEnvironmentUtil.fixDefaultEncodingIfMac(envs, getProject());
    try {
      return PtyProcess.exec(getCommand(), envs, directory != null ? directory : currentProjectFolder());
    }
    catch (IOException e) {
      throw new ExecutionException(e);
    }
  }

  private String currentProjectFolder() {
    final ProjectRootManager projectRootManager = ProjectRootManager.getInstance(myProject);

    final VirtualFile[] roots = projectRootManager.getContentRoots();
    if (roots.length == 1) {
      roots[0].getCanonicalPath();
    }
    final VirtualFile baseDir = myProject.getBaseDir();
    return baseDir == null ? null : baseDir.getCanonicalPath();
  }

  @Override
  protected ProcessHandler createProcessHandler(final PtyProcess process) {
    return new PtyProcessHandler(process);
  }

  @Override
  protected TtyConnector createTtyConnector(PtyProcess process) {
    return new PtyProcessTtyConnector(process, myDefaultCharset);
  }

  @Override
  protected String getTerminalConnectionName(PtyProcess process) {
    return "Local Terminal";
  }

  public String[] getCommand() {
    String[] command;
    String shellPath = TerminalOptionsProvider.getInstance().getShellPath();

    if (SystemInfo.isUnix) {
      File rcFile = findRCFile();

      String shellName = getShellName(shellPath);

      if (rcFile != null && (shellName.equals("bash") || shellName.equals("sh"))) {
        command = new String[]{shellPath, "--rcfile", rcFile.getAbsolutePath(), "-i"};
      }
      else if (hasLoginArgument(shellName)) {
        command = new String[]{shellPath, "--login"};
      }
      else {
        command = shellPath.split(" ");
      }
    }
    else {
      command = new String[]{shellPath};
    }

    return command;
  }

  private static class PtyProcessHandler extends ProcessHandler implements TaskExecutor {

    private final PtyProcess myProcess;
    private final ProcessWaitFor myWaitFor;

    public PtyProcessHandler(PtyProcess process) {
      myProcess = process;
      myWaitFor = new ProcessWaitFor(process, this);
    }

    @Override
    public void startNotify() {
      addProcessListener(new ProcessAdapter() {
        @Override
        public void startNotified(ProcessEvent event) {
          try {
            myWaitFor.setTerminationCallback(new Consumer<Integer>() {
              @Override
              public void consume(Integer integer) {
                notifyProcessTerminated(integer);
              }
            });
          }
          finally {
            removeProcessListener(this);
          }
        }
      });

      super.startNotify();
    }

    @Override
    protected void destroyProcessImpl() {
      myProcess.destroy();
    }

    @Override
    protected void detachProcessImpl() {
      destroyProcessImpl();
    }

    @Override
    public boolean detachIsDefault() {
      return false;
    }

    @Override
    public boolean isSilentlyDestroyOnClose() {
      return true;
    }

    @Nullable
    @Override
    public OutputStream getProcessInput() {
      return myProcess.getOutputStream();
    }

    @Override
    public Future<?> executeTask(Runnable task) {
      return executeOnPooledThread(task);
    }

    protected static Future<?> executeOnPooledThread(Runnable task) {
      final Application application = ApplicationManager.getApplication();

      if (application != null) {
        return application.executeOnPooledThread(task);
      }

      return BaseOSProcessHandler.ExecutorServiceHolder.submit(task);
    }
  }
}
