/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.internal.process;

import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.Validate.isTrue;
import static org.apache.commons.lang3.Validate.notNull;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;

import org.apache.geode.internal.process.ControlFileWatchdog.ControlRequestHandler;
import org.apache.geode.lang.AttachAPINotFoundException;

/**
 * Controls a process using files.
 *
 * @since GemFire 8.0
 */
class FileProcessController implements ProcessController {

  static final long DEFAULT_STATUS_TIMEOUT_MILLIS = 60 * 1000;

  private final long statusTimeoutMillis;
  private final FileControllerParameters parameters;
  private final int pid;

  /**
   * Constructs an instance for controlling a local process.
   *
   * @param parameters details about the controllable process
   * @param pid process id identifying the process to control
   *
   * @throws IllegalArgumentException if pid is not a positive integer
   */
  FileProcessController(final FileControllerParameters parameters, final int pid) {
    this(parameters, pid, DEFAULT_STATUS_TIMEOUT_MILLIS, MILLISECONDS);
  }

  /**
   * Constructs an instance for controlling a local process.
   *
   * @param parameters details about the controllable process
   * @param pid process id identifying the process to control
   * @param timeout the timeout that operations must complete within
   * @param units the units of the timeout
   *
   * @throws IllegalArgumentException if pid is not a positive integer
   */
  FileProcessController(final FileControllerParameters parameters, final int pid,
      final long timeout, final TimeUnit units) {
    notNull(parameters, "Invalid parameters '" + parameters + "' specified");
    isTrue(pid > 0, "Invalid pid '" + pid + "' specified");
    isTrue(timeout >= 0, "Invalid timeout '" + timeout + "' specified");
    notNull(units, "Invalid units '" + units + "' specified");

    this.pid = pid;
    this.parameters = parameters;
    this.statusTimeoutMillis = units.toMillis(timeout);
  }

  @Override
  public int getProcessId() {
    return pid;
  }

  @Override
  public String status()
      throws UnableToControlProcessException, IOException, InterruptedException, TimeoutException {
    return status(parameters.getDirectory(), parameters.getProcessType().getStatusRequestFileName(),
        parameters.getProcessType().getStatusFileName());
  }

  @Override
  public void stop() throws UnableToControlProcessException, IOException {
    stop(parameters.getDirectory(), parameters.getProcessType().getStopRequestFileName());
  }

  @Override
  public void checkPidSupport() {
    throw new AttachAPINotFoundException(
        "The Attach API classes could not be found on the classpath.  Please include JDK tools.jar on the classpath or add the JDK tools.jar to the jre/lib/ext directory.");
  }

  long getStatusTimeoutMillis() {
    return statusTimeoutMillis;
  }

  private void stop(final File workingDir, final String stopRequestFileName) throws IOException {
    File stopRequestFile = new File(workingDir, stopRequestFileName);
    if (!stopRequestFile.exists()) {
      stopRequestFile.createNewFile();
    }
  }

  private String status(final File workingDir, final String statusRequestFileName,
      final String statusFileName) throws IOException, InterruptedException, TimeoutException {
    // monitor for statusFile
    File statusFile = new File(workingDir, statusFileName);
    AtomicReference<String> statusRef = new AtomicReference<>();

    ControlRequestHandler statusHandler = () -> {
      // read the statusFile
      StringBuilder lines = new StringBuilder();
      try (BufferedReader reader = new BufferedReader(new FileReader(statusFile))) {
        reader.lines().forEach(lines::append);
      } finally {
        statusRef.set(lines.toString());
      }
    };

    ControlFileWatchdog statusFileWatchdog =
        new ControlFileWatchdog(workingDir, statusFileName, statusHandler, true);
    statusFileWatchdog.start();

    File statusRequestFile = new File(workingDir, statusRequestFileName);
    if (!statusRequestFile.exists()) {
      statusRequestFile.createNewFile();
    }

    // if timeout invoke stop and then throw TimeoutException
    long start = System.currentTimeMillis();
    while (statusFileWatchdog.isAlive()) {
      Thread.sleep(10);
      if (System.currentTimeMillis() >= start + statusTimeoutMillis) {
        statusFileWatchdog.stop();
        throw new TimeoutException("Timed out waiting for process to create " + statusFile);
      }
    }

    String lines = statusRef.get();
    if (isBlank(lines)) {
      throw new IllegalStateException("Status file '" + statusFile + "' is blank");
    }
    return lines;
  }
}
