// Copyright 2017 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.Consumers.OutErrConsumers;
import java.io.IOException;

/**
 * Basic and only implementation of {@link FutureCommandResult} for use by implementations of
 * {@link SubprocessFactory}.
 */
final class FutureCommandResultImpl implements FutureCommandResult {
  private final Command command;
  private final Subprocess process;
  private final OutErrConsumers outErrConsumers;
  private final boolean killSubprocessOnInterrupt;

  public FutureCommandResultImpl(
      Command command,
      Subprocess process,
      OutErrConsumers outErrConsumers,
      boolean killSubprocessOnInterrupt) {
    this.command = command;
    this.process = process;
    this.outErrConsumers = outErrConsumers;
    this.killSubprocessOnInterrupt = killSubprocessOnInterrupt;
  }

  @Override
  public CommandResult get() throws AbnormalTerminationException {
    TerminationStatus status = waitForProcess(process, killSubprocessOnInterrupt);
    try {
      if (Thread.currentThread().isInterrupted()) {
        outErrConsumers.cancel();
      } else {
        outErrConsumers.waitForCompletion();
      }
    } catch (IOException ioe) {
      CommandResult noOutputResult =
        new CommandResult(CommandResult.EMPTY_OUTPUT,
                          CommandResult.EMPTY_OUTPUT,
                          status);
      if (status.success()) {
        // If command was otherwise successful, throw an exception about this
        throw new AbnormalTerminationException(command, noOutputResult, ioe);
      } else {
        // Otherwise, throw the more important exception -- command
        // was not successful
        String message = status
          + "; also encountered an error while attempting to retrieve output";
        throw status.exited()
            ? new BadExitStatusException(command, noOutputResult, message, ioe)
            : new AbnormalTerminationException(command, noOutputResult, message, ioe);
      }
    } finally {
      process.close();
    }

    CommandResult result = new CommandResult(
        outErrConsumers.getAccumulatedOut(), outErrConsumers.getAccumulatedErr(), status);
    result.logThis();
    if (status.success()) {
      return result;
    } else if (status.exited()) {
      throw new BadExitStatusException(command, result, status.toString());
    } else {
      throw new AbnormalTerminationException(command, result, status.toString());
    }
  }

  private static TerminationStatus waitForProcess(
      Subprocess process, boolean killSubprocessOnInterrupt) {
    boolean wasInterrupted = false;
    try {
      while (true) {
        try {
          process.waitFor();
          return new TerminationStatus(process.exitValue(), process.timedout());
        } catch (InterruptedException ie) {
          wasInterrupted = true;
          if (killSubprocessOnInterrupt) {
            process.destroy();
          }
        }
      }
    } finally {
      // Read this for detailed explanation: http://www.ibm.com/developerworks/library/j-jtp05236/
      if (wasInterrupted) {
        Thread.currentThread().interrupt(); // preserve interrupted status
      }
    }
  }

  @Override
  public void cancel() {
    process.destroy();
  }

  @Override
  public boolean isDone() {
    return process.finished();
  }
}
