/*
 * Copyright 2000-2011 JetBrains s.r.o.
 *
 * 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 jetbrains.buildServer.clouds.vmware.vmrun.local;

import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.openapi.diagnostic.Logger;
import java.util.List;
import jetbrains.buildServer.ExecResult;
import jetbrains.buildServer.SimpleCommandLineProcessRunner;
import jetbrains.buildServer.clouds.CloudException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * @author Eugene Petrenko
 *         Created: 07.12.2009 19:42:15
 */
public abstract class LocalVMCommand {
  private static final Logger LOG = Logger.getInstance(LocalVMCommand.class.getName());

  protected final VMRunSettings mySettings;
  private final GeneralCommandLine myCommandline;
  private boolean myWasStarted = false;
  private Integer myTimeout = 15 * 60;

  public LocalVMCommand(@NotNull final VMRunSettings settings) {
    mySettings = settings;
    myCommandline = new GeneralCommandLine();
  }

  protected void setTimeout(@Nullable Integer seconds) {
    myTimeout = seconds;
  }

  @NotNull
  protected abstract List<String> addArguments();

  protected abstract void processResult(int code, @NotNull String stdOut, @NotNull String stdErr);

  public void startVMRun() {
    if (myWasStarted) {
      throw new CloudException("Process was allready started");
    }
    myWasStarted = true;
    myCommandline.setExePath(mySettings.getVMRunPath().getAbsolutePath());
    myCommandline.addParameter("-T");
    myCommandline.addParameter("player");
    myCommandline.addParameters(addArguments());

    LOG.info("Starting command: " + myCommandline.getCommandLineString());
    final ExecResult result = SimpleCommandLineProcessRunner.runCommand(
      myCommandline,
      new byte[0],
      new SimpleCommandLineProcessRunner.RunCommandEventsAdapter() {
        @Override
        public Integer getOutputIdleSecondsTimeout() {
          return myTimeout;
        }
      }
    );

    LOG.info("Result: " + result.getStdout().trim());
    LOG.info("Result: " + result.getStderr().trim());
    LOG.info("Code: " + result.getExitCode());

    final Throwable ex = result.getException();
    if (ex != null) {
      LOG.warn("Failed to run command: " + ex.getMessage(), ex);
    }

    processResult(result.getExitCode(), result.getStdout().trim(), result.getStderr().trim());
  }
}