// Copyright 2015 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.worker;

import com.google.common.hash.HashCode;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.Reporter;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.vfs.Path;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ProcessBuilder.Redirect;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Interface to a worker process running as a child process.
 *
 * <p>A worker process must follow this protocol to be usable via this class: The worker process is
 * spawned on demand. The worker process is free to exit whenever necessary, as new instances will
 * be relaunched automatically. Communication happens via the WorkerProtocol protobuf, sent to and
 * received from the worker process via stdin / stdout.
 *
 * <p>Other code in Blaze can talk to the worker process via input / output streams provided by this
 * class.
 */
final class Worker {
  private static final AtomicInteger pidCounter = new AtomicInteger();
  private final int workerId;
  private final Process process;
  private final Thread shutdownHook;
  private final HashCode workerFilesHash;

  private Worker(Process process, Thread shutdownHook, int pid, HashCode workerFilesHash) {
    this.process = process;
    this.shutdownHook = shutdownHook;
    this.workerId = pid;
    this.workerFilesHash = workerFilesHash;
  }

  static Worker create(WorkerKey key, Path logDir, Reporter reporter, boolean verbose)
      throws IOException {
    Preconditions.checkNotNull(key);
    Preconditions.checkNotNull(logDir);

    int workerId = pidCounter.getAndIncrement();
    Path logFile = logDir.getRelative("worker-" + workerId + "-" + key.getMnemonic() + ".log");

    String[] command = key.getArgs().toArray(new String[0]);

    // Follows the logic of {@link com.google.devtools.build.lib.shell.Command}.
    File executable = new File(command[0]);
    if (!executable.isAbsolute() && executable.getParent() != null) {
      command[0] = new File(key.getWorkDir().getPathFile(), command[0]).getAbsolutePath();
    }
    ProcessBuilder processBuilder =
        new ProcessBuilder(command)
            .directory(key.getWorkDir().getPathFile())
            .redirectError(Redirect.appendTo(logFile.getPathFile()));
    processBuilder.environment().clear();
    processBuilder.environment().putAll(key.getEnv());

    final Process process = processBuilder.start();

    Thread shutdownHook =
        new Thread() {
          @Override
          public void run() {
            destroyProcess(process);
          }
        };
    Runtime.getRuntime().addShutdownHook(shutdownHook);

    if (verbose) {
      reporter.handle(
          Event.info(
              "Created new "
                  + key.getMnemonic()
                  + " worker (id "
                  + workerId
                  + "), logging to "
                  + logFile));
    }

    return new Worker(process, shutdownHook, workerId, key.getWorkerFilesHash());
  }

  void destroy() {
    Runtime.getRuntime().removeShutdownHook(shutdownHook);
    destroyProcess(process);
  }

  /**
   * Destroys a process and waits for it to exit. This is necessary for the child to not become a
   * zombie.
   *
   * @param process the process to destroy.
   */
  private static void destroyProcess(Process process) {
    boolean wasInterrupted = false;
    try {
      process.destroy();
      while (true) {
        try {
          process.waitFor();
          return;
        } catch (InterruptedException ie) {
          wasInterrupted = true;
        }
      }
    } finally {
      // Read this for detailed explanation: http://www.ibm.com/developerworks/library/j-jtp05236/
      if (wasInterrupted) {
        Thread.currentThread().interrupt(); // preserve interrupted status
      }
    }
  }

  /**
   * Returns a unique id for this worker. This is used to distinguish different worker processes in
   * logs and messages.
   */
  int getWorkerId() {
    return this.workerId;
  }

  HashCode getWorkerFilesHash() {
    return workerFilesHash;
  }

  boolean isAlive() {
    // This is horrible, but Process.isAlive() is only available from Java 8 on and this is the
    // best we can do prior to that.
    try {
      process.exitValue();
      return false;
    } catch (IllegalThreadStateException e) {
      return true;
    }
  }

  InputStream getInputStream() {
    return process.getInputStream();
  }

  OutputStream getOutputStream() {
    return process.getOutputStream();
  }
}
