// Copyright 2018 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.devtools.build.lib.actions.UserExecException;
import com.google.devtools.build.lib.sandbox.SandboxHelpers.SandboxInputs;
import com.google.devtools.build.lib.sandbox.SandboxHelpers.SandboxOutputs;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.worker.WorkerProtocol.WorkRequest;
import com.google.devtools.build.lib.worker.WorkerProtocol.WorkResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Set;
import java.util.logging.Logger;

/** A proxy that talks to the multiplexer */
final class WorkerProxy extends Worker {
  private static final Logger logger = Logger.getLogger(WorkerProxy.class.getName());
  private WorkerMultiplexer workerMultiplexer;
  private String recordingStreamMessage;

  WorkerProxy(
      WorkerKey workerKey,
      int workerId,
      Path workDir,
      Path logFile,
      WorkerMultiplexer workerMultiplexer) {
    super(workerKey, workerId, workDir, logFile);
    this.workerMultiplexer = workerMultiplexer;
  }

  @Override
  void createProcess() throws IOException {
    workerMultiplexer.createProcess(workerKey, workDir, logFile);
  }

  @Override
  boolean isAlive() {
    return workerMultiplexer.isProcessAlive();
  }

  @Override
  public void prepareExecution(
      SandboxInputs inputFiles, SandboxOutputs outputs, Set<PathFragment> workerFiles)
      throws IOException {
    createProcess();
  }

  @Override
  synchronized void destroy() throws IOException {
    super.destroy();
    try {
      WorkerMultiplexerManager.removeInstance(workerKey.hashCode());
    } catch (InterruptedException e) {
      logger.warning(
          "InterruptedException was caught while destroying multiplexer. "
              + "It could because the multiplexer was interrupted.");
    } catch (UserExecException e) {
      logger.warning(e.toString());
    }
  }

  /** Send the WorkRequest to multiplexer. */
  @Override
  void putRequest(WorkRequest request) throws IOException {
    try {
      workerMultiplexer.resetResponseChecker(workerId);
      workerMultiplexer.putRequest(request);
    } catch (InterruptedException e) {
      /**
       * We can't throw InterruptedException to WorkerSpawnRunner because of the principle of
       * override. InterruptedException will happen when Bazel is waiting for semaphore but user
       * terminates the process, so we do nothing here.
       */
      logger.warning(
          "InterruptedException was caught while sending worker request. "
              + "It could because the multiplexer was interrupted.");
    }
  }

  /** Wait for WorkResponse from multiplexer. */
  @Override
  WorkResponse getResponse() throws IOException {
    try {
      InputStream inputStream = workerMultiplexer.getResponse(workerId);
      if (inputStream == null) {
        return null;
      }
      return WorkResponse.parseDelimitedFrom(inputStream);
    } catch (IOException e) {
      recordingStreamMessage = e.toString();
      throw new IOException(
          "IOException was caught while waiting for worker response. "
              + "It could because the worker returned unparseable response.");
    } catch (InterruptedException e) {
      /**
       * We can't throw InterruptedException to WorkerSpawnRunner because of the principle of
       * override. InterruptedException will happen when Bazel is waiting for semaphore but user
       * terminates the process, so we do nothing here.
       */
      logger.warning(
          "InterruptedException was caught while waiting for work response. "
              + "It could because the multiplexer was interrupted.");
    }
    // response can be null when the worker has already closed stdout at this point and thus
    // the InputStream is at EOF.
    return null;
  }

  @Override
  String getRecordingStreamMessage() {
    return recordingStreamMessage;
  }
}
