// Copyright 2016 The Bazel Authors. All rights reserved.
//
// 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 com.google.devtools.build.lib.shell;

import com.google.devtools.build.lib.shell.SubprocessBuilder.StreamAction;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ProcessBuilder.Redirect;

/**
 * A subprocess factory that uses {@link java.lang.ProcessBuilder}.
 */
public class JavaSubprocessFactory implements Subprocess.Factory {

  /**
   * A subprocess backed by a {@link java.lang.Process}.
   */
  private static class JavaSubprocess implements Subprocess {
    private final Process process;

    private JavaSubprocess(Process process) {
      this.process = process;
    }

    @Override
    public boolean destroy() {
      process.destroy();
      return true;
    }

    @Override
    public int exitValue() {
      return process.exitValue();
    }

    @Override
    public boolean finished() {
      try {
        // this seems to be the only non-blocking call for checking liveness
        process.exitValue();
        return true;
      } catch (IllegalThreadStateException e) {
        return false;
      }
    }

    @Override
    public boolean timedout() {
      // Not supported.
      return false;
    }

    @Override
    public void waitFor() throws InterruptedException {
      process.waitFor();
    }

    @Override
    public OutputStream getOutputStream() {
      return process.getOutputStream();
    }

    @Override
    public InputStream getErrorStream() {
      return process.getErrorStream();
    }

    @Override
    public InputStream getInputStream() {
      return process.getInputStream();
    }

    @Override
    public void close() {
      // java.lang.Process doesn't give us a way to clean things up other than #destroy()
    }
  }

  public static final JavaSubprocessFactory INSTANCE = new JavaSubprocessFactory();

  private JavaSubprocessFactory() {
    // We are a singleton
  }

  @Override
  public Subprocess create(SubprocessBuilder params) throws IOException {
    if (params.getTimeoutMillis() >= 0) {
      throw new UnsupportedOperationException("Timeouts are not supported");
    }
    ProcessBuilder builder = new ProcessBuilder();
    builder.command(params.getArgv());
    if (params.getEnv() != null) {
      builder.environment().clear();
      builder.environment().putAll(params.getEnv());
    }

    builder.redirectOutput(getRedirect(params.getStdout(), params.getStdoutFile()));
    builder.redirectError(getRedirect(params.getStderr(), params.getStderrFile()));
    builder.directory(params.getWorkingDirectory());

    return new JavaSubprocess(builder.start());
  }

  /**
   * Returns a {@link ProcessBuilder.Redirect} appropriate for the parameters. If a file redirected
   * to exists, deletes the file before redirecting to it.
   */
  private Redirect getRedirect(StreamAction action, File file) throws IOException {
    switch (action) {
      case DISCARD:
        return Redirect.to(new File("/dev/null"));

      case REDIRECT:
        // We need to use Redirect.appendTo() here, because on older Linux kernels writes are
        // otherwise not atomic and might result in lost log messages:
        // https://lkml.org/lkml/2014/3/3/308
        if (file.exists()) {
          file.delete();
        }
        return Redirect.appendTo(file);

      case STREAM:
        return Redirect.PIPE;

      default:
        throw new IllegalStateException();
    }
  }
}
