/*
 * Copyright (C) 2014 Square, Inc.
 *
 * 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 okio

import java.io.IOException
import java.io.InterruptedIOException
import java.util.concurrent.TimeUnit

actual open class Timeout {
  /**
   * True if `deadlineNanoTime` is defined. There is no equivalent to null or 0 for
   * [System.nanoTime].
   */
  private var hasDeadline = false
  private var deadlineNanoTime = 0L
  private var timeoutNanos = 0L

  /**
   * Wait at most `timeout` time before aborting an operation. Using a per-operation timeout means
   * that as long as forward progress is being made, no sequence of operations will fail.
   *
   * If `timeout == 0`, operations will run indefinitely. (Operating system timeouts may still
   * apply.)
   */
  open fun timeout(timeout: Long, unit: TimeUnit): Timeout {
    require(timeout >= 0) { "timeout < 0: $timeout" }
    timeoutNanos = unit.toNanos(timeout)
    return this
  }

  /** Returns the timeout in nanoseconds, or `0` for no timeout. */
  open fun timeoutNanos(): Long = timeoutNanos

  /** Returns true if a deadline is enabled. */
  open fun hasDeadline(): Boolean = hasDeadline

  /**
   * Returns the [nano time][System.nanoTime] when the deadline will be reached.
   *
   * @throws IllegalStateException if no deadline is set.
   */
  open fun deadlineNanoTime(): Long {
    check(hasDeadline) { "No deadline" }
    return deadlineNanoTime
  }

  /**
   * Sets the [nano time][System.nanoTime] when the deadline will be reached. All operations must
   * complete before this time. Use a deadline to set a maximum bound on the time spent on a
   * sequence of operations.
   */
  open fun deadlineNanoTime(deadlineNanoTime: Long): Timeout {
    this.hasDeadline = true
    this.deadlineNanoTime = deadlineNanoTime
    return this
  }

  /** Set a deadline of now plus `duration` time.  */
  fun deadline(duration: Long, unit: TimeUnit): Timeout {
    require(duration > 0) { "duration <= 0: $duration" }
    return deadlineNanoTime(System.nanoTime() + unit.toNanos(duration))
  }

  /** Clears the timeout. Operating system timeouts may still apply. */
  open fun clearTimeout(): Timeout {
    timeoutNanos = 0
    return this
  }

  /** Clears the deadline. */
  open fun clearDeadline(): Timeout {
    hasDeadline = false
    return this
  }

  /**
   * Throws an [InterruptedIOException] if the deadline has been reached or if the current thread
   * has been interrupted. This method doesn't detect timeouts; that should be implemented to
   * asynchronously abort an in-progress operation.
   */
  @Throws(IOException::class)
  open fun throwIfReached() {
    if (Thread.currentThread().isInterrupted) {
      // If the current thread has been interrupted.
      throw InterruptedIOException("interrupted")
    }

    if (hasDeadline && deadlineNanoTime - System.nanoTime() <= 0) {
      throw InterruptedIOException("deadline reached")
    }
  }

  /**
   * Waits on `monitor` until it is notified. Throws [InterruptedIOException] if either the thread
   * is interrupted or if this timeout elapses before `monitor` is notified. The caller must be
   * synchronized on `monitor`.
   *
   * Here's a sample class that uses `waitUntilNotified()` to await a specific state. Note that the
   * call is made within a loop to avoid unnecessary waiting and to mitigate spurious notifications.
   * ```
   * class Dice {
   *   Random random = new Random();
   *   int latestTotal;
   *
   *   public synchronized void roll() {
   *     latestTotal = 2 + random.nextInt(6) + random.nextInt(6);
   *     System.out.println("Rolled " + latestTotal);
   *     notifyAll();
   *   }
   *
   *   public void rollAtFixedRate(int period, TimeUnit timeUnit) {
   *     Executors.newScheduledThreadPool(0).scheduleAtFixedRate(new Runnable() {
   *       public void run() {
   *         roll();
   *       }
   *     }, 0, period, timeUnit);
   *   }
   *
   *   public synchronized void awaitTotal(Timeout timeout, int total)
   *       throws InterruptedIOException {
   *     while (latestTotal != total) {
   *       timeout.waitUntilNotified(this);
   *     }
   *   }
   * }
   * ```
   */
  @Throws(InterruptedIOException::class)
  fun waitUntilNotified(monitor: Any) {
    try {
      val hasDeadline = hasDeadline()
      val timeoutNanos = timeoutNanos()

      if (!hasDeadline && timeoutNanos == 0L) {
        (monitor as Object).wait() // There is no timeout: wait forever.
        return
      }

      // Compute how long we'll wait.
      val start = System.nanoTime()
      val waitNanos = if (hasDeadline && timeoutNanos != 0L) {
        val deadlineNanos = deadlineNanoTime() - start
        minOf(timeoutNanos, deadlineNanos)
      } else if (hasDeadline) {
        deadlineNanoTime() - start
      } else {
        timeoutNanos
      }

      // Attempt to wait that long. This will break out early if the monitor is notified.
      var elapsedNanos = 0L
      if (waitNanos > 0L) {
        val waitMillis = waitNanos / 1000000L
        (monitor as Object).wait(waitMillis, (waitNanos - waitMillis * 1000000L).toInt())
        elapsedNanos = System.nanoTime() - start
      }

      // Throw if the timeout elapsed before the monitor was notified.
      if (elapsedNanos >= waitNanos) {
        throw InterruptedIOException("timeout")
      }
    } catch (e: InterruptedException) {
      Thread.currentThread().interrupt() // Retain interrupted status.
      throw InterruptedIOException("interrupted")
    }
  }

  /**
   * Applies the minimum intersection between this timeout and `other`, run `block`, then finally
   * rollback this timeout's values.
   */
  inline fun intersectWith(other: Timeout, block: () -> Unit) {
    val originalTimeout = this.timeoutNanos()
    this.timeout(minTimeout(other.timeoutNanos(), this.timeoutNanos()), TimeUnit.NANOSECONDS)

    if (this.hasDeadline()) {
      val originalDeadline = this.deadlineNanoTime()
      if (other.hasDeadline()) {
        this.deadlineNanoTime(Math.min(this.deadlineNanoTime(), other.deadlineNanoTime()))
      }
      try {
        block()
      } finally {
        this.timeout(originalTimeout, TimeUnit.NANOSECONDS)
        if (other.hasDeadline()) {
          this.deadlineNanoTime(originalDeadline)
        }
      }
    } else {
      if (other.hasDeadline()) {
        this.deadlineNanoTime(other.deadlineNanoTime())
      }
      try {
        block()
      } finally {
        this.timeout(originalTimeout, TimeUnit.NANOSECONDS)
        if (other.hasDeadline()) {
          this.clearDeadline()
        }
      }
    }
  }

  actual companion object {
    @JvmField actual val NONE: Timeout = object : Timeout() {
      override fun timeout(timeout: Long, unit: TimeUnit): Timeout = this

      override fun deadlineNanoTime(deadlineNanoTime: Long): Timeout = this

      override fun throwIfReached() {}
    }

    fun minTimeout(aNanos: Long, bNanos: Long) = when {
      aNanos == 0L -> bNanos
      bNanos == 0L -> aNanos
      aNanos < bNanos -> aNanos
      else -> bNanos
    }
  }
}
