/*
 * 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.cache;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;

import org.apache.logging.log4j.Logger;
import org.jgroups.annotations.GuardedBy;

import org.apache.geode.CancelException;
import org.apache.geode.InternalGemFireError;
import org.apache.geode.SystemFailure;
import org.apache.geode.annotations.internal.MakeNotStatic;
import org.apache.geode.annotations.internal.MutableForTesting;
import org.apache.geode.cache.CacheException;
import org.apache.geode.cache.EntryNotFoundException;
import org.apache.geode.cache.ExpirationAction;
import org.apache.geode.cache.ExpirationAttributes;
import org.apache.geode.cache.RegionDestroyedException;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.internal.SystemTimer;
import org.apache.geode.internal.logging.CoreLoggingExecutors;
import org.apache.geode.internal.tcp.ConnectionTable;
import org.apache.geode.logging.internal.log4j.api.LogService;
import org.apache.geode.util.internal.GeodeGlossary;

/**
 * ExpiryTask represents a timeout event for expiration
 */
public abstract class ExpiryTask extends SystemTimer.SystemTimerTask {

  private static final Logger logger = LogService.getLogger();

  private LocalRegion region; // no longer final so cancel can null it out see bug 37574

  @MakeNotStatic
  private static final ExecutorService executor;

  static {
    // default to inline expiry to fix bug 37115
    int nThreads = Integer.getInteger(GeodeGlossary.GEMFIRE_PREFIX + "EXPIRY_THREADS", 0);
    if (nThreads > 0) {
      executor = CoreLoggingExecutors.newThreadPoolWithSynchronousFeed(nThreads, "Expiry ",
          ExpiryTask::doExpiryThread);
    } else {
      executor = null;
    }
  }

  private static void doExpiryThread(Runnable command) {
    ConnectionTable.threadWantsSharedResources();
    try {
      command.run();
    } finally {
      ConnectionTable.releaseThreadsSockets();
    }
  }

  protected ExpiryTask(LocalRegion region) {
    this.region = region;
  }

  protected abstract ExpirationAttributes getIdleAttributes();

  protected abstract ExpirationAttributes getTTLAttributes();

  /**
   * @return the absolute time (ms since Jan 1, 1970) at which this region expires, due to either
   *         time-to-live or idle-timeout (whichever will occur first), or 0 if neither are used.
   */
  public long getExpirationTime() throws EntryNotFoundException {
    long ttl = getTTLExpirationTime();
    long idle = getIdleExpirationTime();
    if (ttl == 0) {
      return idle;
    } else if (idle == 0) {
      return ttl;
    }
    return Math.min(ttl, idle);
  }

  /** Return the absolute time when TTL expiration occurs, or 0 if not used */
  public long getTTLExpirationTime() throws EntryNotFoundException {
    long ttl = getTTLAttributes().getTimeout();
    long tilt = 0;
    if (ttl > 0) {
      ttl = normalizeToMillis(ttl);
      tilt = getLastModifiedTime() + ttl;
    }
    return tilt;
  }

  /** Return true if the expiration unit is seconds; false if milliseconds */
  public boolean isExpiryUnitSeconds() {
    boolean isSeconds = getLocalRegion() == null || !getLocalRegion().isExpiryUnitsMilliseconds();
    return isSeconds;
  }

  /**
   * Return the given timestamp as milliseconds.
   * If the given secondsOrMillis is already millis then no conversion is needed.
   */
  public long normalizeToMillis(long secondsOrMillis) {
    if (isExpiryUnitSeconds()) {
      return TimeUnit.SECONDS.toMillis(secondsOrMillis);
    }
    return secondsOrMillis;
  }

  private static final long HALF_A_SECOND_IN_MILLIS = TimeUnit.SECONDS.toMillis(1) / 2;

  public boolean hasExpired(long now, long expireTime) {
    if (isExpiryUnitSeconds()) {
      // Units are seconds but the internal timestamps are milliseconds.
      // To prevent a needless reschedule, bump now by half a second.
      now += HALF_A_SECOND_IN_MILLIS;
    }
    return now >= expireTime;
  }

  /** Return the absolute time when idle expiration occurs, or 0 if not used */
  public long getIdleExpirationTime() throws EntryNotFoundException {
    long idle = getIdleTimeoutInMillis();
    if (idle > 0) {
      return getLastAccessedTime() + idle;
    }
    return 0L;
  }

  protected long getIdleTimeoutInMillis() {
    long idle = getIdleAttributes().getTimeout();
    if (idle > 0) {
      idle = normalizeToMillis(idle);
    }
    return idle;
  }

  /**
   * Returns the number of milliseconds until this task should expire. The return value will never
   * be negative.
   */
  long getExpiryMillis() throws EntryNotFoundException {
    long extm = getExpirationTime() - getNow();
    if (extm < 0L) {
      return 0L;
    } else {
      return extm;
    }
  }

  /**
   * Return true if current task could have expired. Return false if expiration is impossible.
   */
  protected boolean isExpirationPossible() throws EntryNotFoundException {
    long expTime = getExpirationTime();
    if (expTime > 0L) {
      long now = getNow();
      if (hasExpired(now, expTime)) {
        if (isIdleExpiredOnOthers()) {
          return true;
        } else {
          // our last access time was reset so recheck
          expTime = getExpirationTime();
          return expTime > 0L && hasExpired(now, expTime);
        }
      }
    }
    return false;
  }

  /**
   * Added for GEODE-3764.
   *
   * @return true if other members last access time indicates we have expired
   */
  protected boolean isIdleExpiredOnOthers() throws EntryNotFoundException {
    // by default return true since we don't need to check with others
    return true;
  }

  /**
   * Returns false if the region reliability state does not allow this expiry task to fire.
   */
  protected boolean isExpirationAllowed() {
    return getLocalRegion().isExpirationAllowed(this);
  }

  protected void performTimeout() throws CacheException {
    if (logger.isDebugEnabled()) {
      logger.debug("{}.performTimeout(): getExpirationTime() returns {}", toString(),
          getExpirationTime());
    }

    getLocalRegion().performExpiryTimeout(this);
  }

  protected abstract void basicPerformTimeout(boolean isPending) throws CacheException;

  @GuardedBy("suspendLock")
  @MakeNotStatic
  private static boolean expirationSuspended = false;

  @MakeNotStatic
  private static final Object suspendLock = new Object();

  /**
   * Test method that causes expiration to be suspended until permitExpiration is called.
   *
   * @since GemFire 5.0
   */
  public static void suspendExpiration() {
    synchronized (suspendLock) {
      expirationSuspended = true;
    }
  }

  public static void permitExpiration() {
    synchronized (suspendLock) {
      expirationSuspended = false;
      suspendLock.notifyAll();
    }
  }

  /**
   * Wait until permission is given for expiration to be done. Tests are allowed to suspend
   * expiration.
   *
   * @since GemFire 5.0
   */
  private void waitOnExpirationSuspension() {
    for (;;) {
      getLocalRegion().getCancelCriterion().checkCancelInProgress(null);
      synchronized (suspendLock) {
        boolean interrupted = Thread.interrupted();
        try {
          while (expirationSuspended) {
            suspendLock.wait();
          }
          break;
        } catch (InterruptedException ex) {
          interrupted = true;
          getLocalRegion().getCancelCriterion().checkCancelInProgress(null);
          // keep going, we can't cancel
        } finally {
          if (interrupted) {
            Thread.currentThread().interrupt();
          }
        }
      } // synchronized
    } // for
  }

  protected boolean expire(boolean isPending) throws CacheException {
    ExpirationAction action = getAction();
    if (action == null) {
      return false;
    }
    boolean result = expire(action, isPending);
    if (result && expiryTaskListener != null) {
      expiryTaskListener.afterExpire(this);
    }
    return result;
  }

  /**
   * Why did this expire?
   *
   * @return the action to perform or null if NONE
   */
  protected ExpirationAction getAction() {
    long ttl = getTTLExpirationTime();
    long idle = getIdleExpirationTime();
    if (ttl == 0) {
      if (idle == 0) {
        return null;
      }
      return getIdleAttributes().getAction();
    }
    if (idle == 0) {
      // we know ttl != 0
      return getTTLAttributes().getAction();
    }
    // Neither is 0
    if (idle < ttl) {
      return getIdleAttributes().getAction();
    }
    return getTTLAttributes().getAction();
  }

  /** Returns true if the ExpirationAction is a distributed action. */
  protected boolean isDistributedAction() {
    ExpirationAction action = getAction();
    return action != null && (action.isInvalidate() || action.isDestroy());
  }

  LocalRegion getLocalRegion() {
    return region;
  }


  protected boolean expire(ExpirationAction action, boolean isPending) throws CacheException {
    if (action.isInvalidate()) {
      return invalidate();
    }
    if (action.isDestroy()) {
      return destroy(isPending);
    }
    if (action.isLocalInvalidate()) {
      return localInvalidate();
    }
    if (action.isLocalDestroy()) {
      return localDestroy();
    }
    throw new InternalGemFireError(
        String.format("unrecognized expiration action: %s", action));
  }

  /**
   * Cancel this task
   */
  @Override
  public boolean cancel() {
    boolean superCancel = super.cancel();
    LocalRegion lr = getLocalRegion();
    if (lr != null) {
      if (superCancel) {
        region = null; // this is the only place it is nulled
      }
    }
    return superCancel;
  }

  /**
   * An ExpiryTask is sent run() to perform its task. Note that this run() method should never throw
   * an exception - otherwise, it takes out the java.util.Timer thread, causing an exception
   * whenever we try to schedule more expiration tasks.
   */
  @Override
  public void run2() {
    try {
      if (executor != null) {
        executor.execute(this::runInThreadPool);
      } else {
        // inline
        runInThreadPool();
      }
    } catch (RejectedExecutionException ex) {
      try {
        if (logger.isDebugEnabled()) {
          logger.debug("Rejected execution in expiration task", ex);
        }
      } catch (VirtualMachineError err) {
        SystemFailure.initiateFailure(err);
        // If this ever returns, rethrow the error. We're poisoned
        // now, so don't let this thread continue.
        throw err;
      } catch (Throwable t) {
        // Whenever you catch Error or Throwable, you must also
        // catch VirtualMachineError (see above). However, there is
        // _still_ a possibility that you are dealing with a cascading
        // error condition, so you also need to check to see if the JVM
        // is still usable:
        SystemFailure.checkFailure();
        // for surviving and debugging exceptions getting the logger
        t.printStackTrace();
      }
    } catch (CancelException e) {
      return; // just bail
    } catch (VirtualMachineError err) {
      SystemFailure.initiateFailure(err);
      // If this ever returns, rethrow the error. We're poisoned
      // now, so don't let this thread continue.
      throw err;
    } catch (Throwable ex) {
      // Whenever you catch Error or Throwable, you must also
      // catch VirtualMachineError (see above). However, there is
      // _still_ a possibility that you are dealing with a cascading
      // error condition, so you also need to check to see if the JVM
      // is still usable:
      SystemFailure.checkFailure();
      logger.fatal("Exception in expiration task", ex);
    }
  }

  protected void runInThreadPool() {
    try {
      if (isCacheClosing() || getLocalRegion().isClosed() || getLocalRegion().isDestroyed()) {
        return;
      }
      waitOnExpirationSuspension();
      if (logger.isTraceEnabled()) {
        logger.trace("{} is fired", this);
      }

      // do our work...
      performTimeout();
    } catch (RegionDestroyedException re) {
      // Ignore - our job is done
    } catch (EntryNotFoundException ex) {
      // Ignore
    } catch (CancelException ex) {
      // ignore
    } catch (VirtualMachineError err) {
      SystemFailure.initiateFailure(err);
      // If this ever returns, rethrow the error. We're poisoned
      // now, so don't let this thread continue.
      throw err;
    } catch (Throwable ex) {
      // Whenever you catch Error or Throwable, you must also
      // catch VirtualMachineError (see above). However, there is
      // _still_ a possibility that you are dealing with a cascading
      // error condition, so you also need to check to see if the JVM
      // is still usable:
      SystemFailure.checkFailure();
      logger.fatal("Exception in expiration task", ex);
    } finally {
      if (expiryTaskListener != null) {
        expiryTaskListener.afterTaskRan(this);
      }
    }
  }

  protected boolean isCacheClosing() {
    return getLocalRegion().getCache().isClosed();
  }

  /**
   * Reschedule (or not) this task for later consideration
   */
  protected abstract void reschedule() throws CacheException;

  @Override
  public String toString() {
    String expTtl = "<unavailable>";
    String expIdle = "<unavailable>";
    try {
      if (getTTLAttributes() != null) {
        expTtl = String.valueOf(getTTLExpirationTime());
      }
      if (getIdleAttributes() != null) {
        expIdle = String.valueOf(getIdleExpirationTime());
      }
    } catch (VirtualMachineError err) {
      SystemFailure.initiateFailure(err);
      // If this ever returns, rethrow the error. We're poisoned
      // now, so don't let this thread continue.
      throw err;
    } catch (Throwable t) {
      // Whenever you catch Error or Throwable, you must also
      // catch VirtualMachineError (see above). However, there is
      // _still_ a possibility that you are dealing with a cascading
      // error condition, so you also need to check to see if the JVM
      // is still usable:
      SystemFailure.checkFailure();
    }
    return super.toString() + " for " + getLocalRegion() + ", ttl expiration time: " + expTtl
        + ", idle expiration time: " + expIdle + ("[now:" + calculateNow() + "]");
  }

  ////// Abstract methods ///////

  protected abstract long getLastModifiedTime() throws EntryNotFoundException;

  protected abstract long getLastAccessedTime() throws EntryNotFoundException;

  protected abstract boolean invalidate() throws CacheException;

  protected abstract boolean destroy(boolean isPending) throws CacheException;

  protected abstract boolean localInvalidate() throws EntryNotFoundException;

  protected abstract boolean localDestroy() throws CacheException;

  protected abstract void addExpiryTask() throws EntryNotFoundException;

  public abstract boolean isPending();

  public abstract Object getKey();

  private static final ThreadLocal<Long> now = new ThreadLocal<>();

  /**
   * To reduce the number of times we need to call calculateNow, you can call this method to set now
   * in a thread local. When the run returns the thread local is cleared.
   */
  static void doWithNowSet(LocalRegion lr, Runnable runnable) {
    now.set(calculateNow(lr.getCache()));
    try {
      runnable.run();
    } finally {
      now.remove();
    }
  }

  /**
   * Returns the current time in milliseconds. If the current thread has set the now thread local
   * then that time is return. Otherwise now is calculated and returned.
   *
   * @return the current time in milliseconds
   */
  protected long getNow() {
    long result;
    Long tl = now.get();
    if (tl != null) {
      result = tl;
    } else {
      result = calculateNow();
    }
    return result;
  }

  public long calculateNow() {
    return calculateNow(getLocalRegion().getCache());
  }

  public static long calculateNow(InternalCache cache) {
    if (cache != null) {
      // Use cache.cacheTimeMillis here. See bug 52267.
      InternalDistributedSystem ids = cache.getInternalDistributedSystem();
      if (ids != null) {
        return ids.getClock().cacheTimeMillis();
      }
    }
    return 0L;
  }

  // Should only be set by unit tests
  @MutableForTesting
  public static ExpiryTaskListener expiryTaskListener;

  /**
   * Used by tests to determine if events related to an ExpiryTask have happened.
   */
  public interface ExpiryTaskListener {
    /**
     * Called after entry is schedule for expiration.
     */
    void afterSchedule(ExpiryTask et);

    /**
     * Called after the given expiry task has run. This means that the time it was originally
     * scheduled to run has elapsed and the scheduler has run the task. While running the task it
     * may decide to expire it or reschedule it.
     */
    void afterTaskRan(ExpiryTask et);

    /**
     * Called after the given expiry task has been rescheduled. afterTaskRan can still be called on
     * the same task. In some cases a task is rescheduled without expiring it. In others it is
     * expired and rescheduled.
     */
    void afterReschedule(ExpiryTask et);

    /**
     * Called after the given expiry task has expired.
     */
    void afterExpire(ExpiryTask et);

    /**
     * Called when task has been canceled
     */
    void afterCancel(ExpiryTask et);

  }
}
