/*
 * 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 org.apache.commons.lang3.Validate.notEmpty;
import static org.apache.commons.lang3.Validate.notNull;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

import org.apache.logging.log4j.Logger;

import org.apache.geode.internal.logging.LogService;
import org.apache.geode.internal.logging.LoggingThread;

/**
 * Invokes a ControlRequestHandler when a control file has been created.
 *
 * @since GemFire 8.0
 */
class ControlFileWatchdog implements Runnable {
  private static final Logger logger = LogService.getLogger();

  private static final long STOP_TIMEOUT_MILLIS = 60 * 1000;
  private static final long LOOP_INTERVAL_MILLIS = 1000;

  private final File directory;
  private final File file;
  private final ControlRequestHandler requestHandler;
  private final boolean stopAfterRequest;

  private Thread thread;
  private boolean alive;

  ControlFileWatchdog(final File directory, final String fileName,
      final ControlRequestHandler requestHandler, final boolean stopAfterRequest) {
    notNull(directory, "Invalid directory '" + directory + "' specified");
    notEmpty(fileName, "Invalid fileName '" + fileName + "' specified");
    notNull(requestHandler, "Invalid requestHandler '" + requestHandler + "' specified");

    this.directory = directory;
    this.file = new File(directory, fileName);
    this.requestHandler = requestHandler;
    this.stopAfterRequest = stopAfterRequest;
  }

  @Override
  public void run() {
    try { // always set alive before stopping
      while (isAlive()) {
        doWork();
      }
    } finally {
      synchronized (this) {
        alive = false;
      }
    }
  }

  private void doWork() {
    try { // handle handle exceptions
      if (file.exists()) {
        try { // always check stopAfterRequest after handleRequest
          handleRequest();
        } finally {
          if (stopAfterRequest) {
            stopMe();
          }
        }
      }
      Thread.sleep(LOOP_INTERVAL_MILLIS);
    } catch (InterruptedException ignored) {
      Thread.currentThread().interrupt();
      // allow to loop around and check isAlive()
    } catch (IOException ignored) {
      logger.error(
          "Unable to control process with {}. Please add tools.jar from JDK to classpath for improved process control.",
          file);
      // allow to loop around and check isAlive()
    }
  }

  private void handleRequest() throws IOException {
    try { // always delete file after invoking handler
      requestHandler.handleRequest();
    } finally {
      try {
        file.delete();
      } catch (SecurityException e) {
        logger.warn("Unable to delete {}", file, e);
      }
    }
  }

  void start() {
    synchronized (this) {
      if (thread == null) {
        thread = new LoggingThread(createThreadName(), this);
        alive = true;
        deleteExistingStatusResponseFile();
        thread.start();
      }
    }
  }

  void stop() throws InterruptedException {
    Thread stopping = null;
    synchronized (this) {
      if (thread != null) {
        alive = false;
        if (thread != Thread.currentThread()) {
          thread.interrupt();
          stopping = thread;
        }
        thread = null;
      }
    }
    if (stopping != null) {
      stopping.join(STOP_TIMEOUT_MILLIS);
    }
  }

  boolean isAlive() {
    synchronized (this) {
      return alive;
    }
  }

  private void stopMe() {
    synchronized (this) {
      if (thread != null) {
        alive = false;
        thread = null;
      }
    }
  }

  private void deleteExistingStatusResponseFile() {
    try {
      Files.deleteIfExists(file.toPath());
    } catch (IOException e) {
      logger.warn("Unable to delete file", e);
    }
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder(getClass().getSimpleName());
    sb.append('@').append(System.identityHashCode(this)).append('{');
    sb.append("directory=").append(directory);
    sb.append(", file=").append(file);
    sb.append(", alive=").append(alive); // not synchronized
    sb.append(", stopAfterRequest=").append(stopAfterRequest);
    return sb.append('}').toString();
  }

  private String createThreadName() {
    return getClass().getSimpleName() + '@' + Integer.toHexString(hashCode()) + " monitoring "
        + file.getName();
  }

  /**
   * Defines the callback to be invoked when the control file exists.
   */
  interface ControlRequestHandler {
    void handleRequest() throws IOException;
  }
}
