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

import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.logging.log4j.Logger;

import org.apache.geode.CancelException;
import org.apache.geode.SystemFailure;
import org.apache.geode.annotations.internal.MakeNotStatic;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.logging.internal.log4j.api.LogService;

/**
 * Instances of this class are like {@link Timer}, but are associated with a "swarm", which can be
 * cancelled as a group with {@link #cancelSwarm(Object)}.
 *
 * @see Timer
 * @see TimerTask
 *
 *      TODO -- with Java 1.5, this will be a template type so that the swarm's class can be
 *      specified.
 */
public class SystemTimer {
  private static final Logger logger = LogService.getLogger();

  private static final boolean isIBM =
      "IBM Corporation".equals(System.getProperty("java.vm.vendor"));

  /**
   * Extra debugging for this class
   */
  // private static final boolean DEBUG = true;
  static final boolean DEBUG = false;

  /**
   * the underlying {@link Timer}
   */
  private final Timer timer;

  /**
   * True if this timer has been cancelled
   */
  private boolean cancelled = false;

  /**
   * the swarm to which this timer belongs
   */
  private final Object /* T */ swarm;

  @Override
  public String toString() {
    StringBuffer sb = new StringBuffer();
    sb.append("SystemTimer[");
    sb.append("swarm = " + swarm);
    // sb.append("; timer = " + timer);
    sb.append("]");
    return sb.toString();
  }

  /**
   * List of all of the swarms in the system
   *
   * @guarded.By self
   */
  // <T, HashMap<Object, ArrayList<WeakReference<SystemTimer>>>>
  @MakeNotStatic
  private static final HashMap allSwarms = new HashMap();

  /**
   * Add the given timer is in the given swarm. Used only by constructors.
   *
   * @param swarm swarm to add the timer to
   * @param t timer to add
   */
  private static void addToSwarm(Object /* T */ swarm, SystemTimer t) {
    final boolean isDebugEnabled = logger.isTraceEnabled();
    // Get or add list of timers for this swarm...
    ArrayList /* ArrayList<WeakReference<SystemTimer>> */ swarmSet;
    synchronized (allSwarms) {
      swarmSet = (ArrayList) allSwarms.get(swarm);
      if (swarmSet == null) {
        if (isDebugEnabled) {
          logger.trace("SystemTimer#addToSwarm: created swarm {}", swarm);
        }
        swarmSet = new ArrayList();
        allSwarms.put(swarm, swarmSet);
      }
    } // synchronized

    // Add the timer to the swarm's list
    if (isDebugEnabled) {
      logger.trace("SystemTimer#addToSwarm: adding timer <{}>", t);
    }
    WeakReference /* WeakReference<SystemTimer> */ wr = new WeakReference(t);
    synchronized (swarmSet) {
      swarmSet.add(wr);
    } // synchronized
  }

  /**
   * time that the last sweep was done
   *
   * @see #sweepAllSwarms
   */
  @MakeNotStatic
  private static long lastSweepAllTime = 0;

  /**
   * Interval, in milliseconds, to sweep all swarms, measured from when the last sweep finished
   *
   * @see #sweepAllSwarms
   */
  private static final long SWEEP_ALL_INTERVAL = 2 * 60 * 1000; // 2 minutes

  /**
   * Manually garbage collect {@link #allSwarms}, if it hasn't happened in a while.
   *
   * @see #lastSweepAllTime
   */
  private static void sweepAllSwarms() {
    if (System.currentTimeMillis() < lastSweepAllTime + SWEEP_ALL_INTERVAL) {
      // Too soon.
      return;
    }
    final boolean isDebugEnabled = logger.isTraceEnabled();
    synchronized (allSwarms) {
      Iterator it = allSwarms.entrySet().iterator();
      while (it.hasNext()) { // iterate over allSwarms
        Map.Entry entry = (Map.Entry) it.next();
        ArrayList swarm = (ArrayList) entry.getValue();
        synchronized (swarm) {
          Iterator it2 = swarm.iterator();
          while (it2.hasNext()) { // iterate over current swarm
            WeakReference wr = (WeakReference) it2.next();
            SystemTimer st = (SystemTimer) wr.get();
            if (st == null) {
              // Remove stale reference
              it2.remove();
              continue;
            }
            // Get rid of a cancelled timer; it's not interesting.
            if (st.cancelled) {
              it2.remove();
              continue;
            }
          } // iterate over current swarm
          if (swarm.size() == 0) { // Remove unused swarm
            it.remove();
            if (isDebugEnabled) {
              logger.trace("SystemTimer#sweepAllSwarms: removed unused swarm {}", entry.getKey());
            }
          } // Remove unused swarm
        } // synchronized swarm
      } // iterate over allSwarms
    } // synchronized allSwarms

    // Collect time at END of sweep. It means an extra call to the system
    // timer, but makes this potentially less active.
    lastSweepAllTime = System.currentTimeMillis();
  }

  /**
   * Remove given timer from the swarm.
   *
   * @param t timer to remove
   *
   * @see #cancel()
   */
  private static void removeFromSwarm(SystemTimer t) {
    final boolean isDebugEnabled = logger.isTraceEnabled();
    synchronized (allSwarms) {
      // Get timer's swarm
      ArrayList swarmSet = (ArrayList) allSwarms.get(t.swarm);
      if (swarmSet == null) {
        if (isDebugEnabled) {
          logger.trace("SystemTimer#removeFromSwarm: timer already removed: {}", t);
        }
        return; // already gone
      }

      // Remove timer from swarm
      if (isDebugEnabled) {
        logger.trace("SystemTimer#removeFromSwarm: removing timer <{}>", t);
      }
      synchronized (swarmSet) {
        Iterator it = swarmSet.iterator();
        while (it.hasNext()) {
          WeakReference ref = (WeakReference) it.next();
          SystemTimer t2 = (SystemTimer) ref.get();
          if (t2 == null) {
            // Since we've discovered an empty reference, we should remove it.
            it.remove();
            continue;
          }
          if (t2 == t) {
            it.remove();
            // Don't keep sweeping once we've found it; just quit.
            break;
          }
          if (t2.cancelled) {
            // But if we happen to run across a cancelled timer,
            // remove it.
            it.remove();
            continue;
          }
        } // while

        // While we're here, if the swarm has gone to zero size,
        // we should remove it.
        if (swarmSet.size() == 0) {
          allSwarms.remove(t.swarm); // last reference
          if (isDebugEnabled) {
            logger.trace("SystemTimer#removeFromSwarm: removed last reference to {}", t.swarm);
          }
        }
      } // synchronized swarmSet
    } // synchronized allSwarms

    sweepAllSwarms(); // Occasionally check global list, use any available logger :-)
  }

  /**
   * Cancel all outstanding timers
   *
   * @param swarm the swarm to cancel
   */
  public static void cancelSwarm(Object /* T */ swarm) {
    Assert.assertTrue(swarm instanceof InternalDistributedSystem); // TODO
    // Find the swarmSet and remove it
    ArrayList swarmSet;
    synchronized (allSwarms) {
      swarmSet = (ArrayList) allSwarms.get(swarm);
      if (swarmSet == null) {
        return; // already cancelled
      }
      // Remove before releasing synchronization, so any fresh timer ends up
      // in a new set with same key
      allSwarms.remove(swarmSet);
    } // synchronized

    // Empty the swarmSet
    synchronized (swarmSet) {
      Iterator it = swarmSet.iterator();
      while (it.hasNext()) {
        WeakReference wr = (WeakReference) it.next();
        SystemTimer st = (SystemTimer) wr.get();
        // it.remove(); Not necessary, we're emptying the list...
        if (st != null) {
          st.cancelled = true; // for safety :-)
          st.timer.cancel(); // st.cancel() would just search for it again
        }
      } // while
    } // synchronized
  }

  public int timerPurge() {
    if (logger.isTraceEnabled()) {
      logger.trace("SystemTimer#timerPurge of {}", this);
    }

    // Fix 39585, IBM's java.util.timer's purge() has stack overflow issue
    if (isIBM) {
      return 0;
    }
    return this.timer.purge();
  }

  // This creates a non-daemon timer thread. We don't EVER do this...
  // /**
  // * @see Timer#Timer()
  // *
  // * @param swarm the swarm this timer belongs to
  // */
  // public SystemTimer(DistributedSystem swarm) {
  // this.timer = new Timer();
  // this.swarm = swarm;
  // addToSwarm(swarm, this);
  // }

  /**
   * @see Timer#Timer(boolean)
   * @param swarm the swarm this timer belongs to, currently must be a DistributedSystem
   * @param isDaemon whether the timer is a daemon. Must be true for GemFire use.
   */
  public SystemTimer(Object /* T */ swarm, boolean isDaemon) {
    Assert.assertTrue(isDaemon); // we don't currently allow non-daemon timers
    Assert.assertTrue(swarm instanceof InternalDistributedSystem,
        "Attempt to create swarm on " + swarm); // TODO allow template class?
    this.timer = new Timer(isDaemon);
    this.swarm = swarm;
    addToSwarm(swarm, this);
  }

  /**
   * @param name the name to give the timer thread
   * @param swarm the swarm this timer belongs to, currently must be a DistributedMember
   * @param isDaemon whether the timer is a daemon. Must be true for GemFire use.
   */
  public SystemTimer(String name, Object /* T */ swarm, boolean isDaemon) {
    Assert.assertTrue(isDaemon); // we don't currently allow non-daemon timers
    Assert.assertTrue(swarm instanceof InternalDistributedSystem,
        "Attempt to create swarm on " + swarm); // TODO allow template class?
    this.timer = new Timer(name, isDaemon);
    this.swarm = swarm;
    addToSwarm(swarm, this);
  }

  private void checkCancelled() throws IllegalStateException {
    if (this.cancelled) {
      throw new IllegalStateException("This timer has been cancelled.");
    }
  }

  /**
   * @see Timer#schedule(TimerTask, long)
   */
  public void schedule(SystemTimerTask task, long delay) {
    checkCancelled();
    if (logger.isTraceEnabled()) {
      Date tilt = new Date(System.currentTimeMillis() + delay);
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
      logger.trace("SystemTimer#schedule (long): {}: expect task {} to fire around {}", this, task,
          sdf.format(tilt));
    }
    timer.schedule(task, delay);
  }

  /**
   * @see Timer#schedule(TimerTask, Date)
   */
  public void schedule(SystemTimerTask task, Date time) {
    checkCancelled();
    if (logger.isTraceEnabled()) {
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
      logger.trace("SystemTimer#schedule (Date): {}: expect task {} to fire around {}", this, task,
          sdf.format(time));
    }
    timer.schedule(task, time);
  }

  // Not currently used, so don't complicate things
  // /**
  // * @see Timer#schedule(TimerTask, long, long)
  // */
  // public void schedule(SystemTimerTask task, long delay, long period) {
  // // TODO add debug statement
  // checkCancelled();
  // timer.schedule(task, delay, period);
  // }

  // Not currently used, so don't complicate things
  // /**
  // * @see Timer#schedule(TimerTask, Date, long)
  // */
  // public void schedule(SystemTimerTask task, Date firstTime, long period) {
  // // TODO add debug statement
  // checkCancelled();
  // timer.schedule(task, firstTime, period);
  // }

  /**
   * @see Timer#scheduleAtFixedRate(TimerTask, long, long)
   */
  public void scheduleAtFixedRate(SystemTimerTask task, long delay, long period) {
    // TODO add debug statement
    checkCancelled();
    timer.scheduleAtFixedRate(task, delay, period);
  }

  /**
   * @see Timer#schedule(TimerTask, long, long)
   */
  public void schedule(SystemTimerTask task, long delay, long period) {
    // TODO add debug statement
    checkCancelled();
    timer.schedule(task, delay, period);
  }

  // Not currently used, so don't complicate things
  // /**
  // * @see Timer#scheduleAtFixedRate(TimerTask, Date, long)
  // */
  // public void scheduleAtFixedRate(SystemTimerTask task, Date firstTime,
  // long period) {
  // // TODO add debug statement
  // checkCancelled();
  // timer.scheduleAtFixedRate(task, firstTime, period);
  // }


  /**
   * @see Timer#cancel()
   */
  public void cancel() {
    this.cancelled = true;
    timer.cancel();
    removeFromSwarm(this);
  }

  /**
   * Cover class to track behavior of scheduled tasks
   *
   * @see TimerTask
   */
  public abstract static class SystemTimerTask extends TimerTask {
    protected static final Logger logger = LogService.getLogger();

    /**
     * This is your executed action
     */
    public abstract void run2();

    /**
     * Does debug logging, catches critical errors, then delegates to {@link #run2()}
     */
    @Override
    public void run() {
      final boolean isDebugEnabled = logger.isTraceEnabled();
      if (isDebugEnabled) {
        logger.trace("SystemTimer.MyTask: starting {}", this);
      }
      try {
        this.run2();
      } catch (CancelException ignore) {
        // ignore: TimerThreads can fire during or near cache closure
      } catch (VirtualMachineError e) {
        SystemFailure.initiateFailure(e);
        throw e;
      } catch (Throwable t) {
        SystemFailure.checkFailure();
        logger.warn(String.format("Timer task <%s> encountered exception", this), t);
        // Don't rethrow, it will just get eaten and kill the timer
      }
      if (isDebugEnabled) {
        logger.trace("SystemTimer.MyTask: finished {}", this);
      }
    }
  }

}
