/**
 * 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.hcatalog.templeton.tool;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Date;

import org.apache.hadoop.conf.Configuration;
import org.apache.zookeeper.ZooKeeper;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * This does periodic cleanup
 */
public class ZooKeeperCleanup extends Thread {
    protected Configuration appConf;

    // The interval to wake up and check the queue
    public static final String ZK_CLEANUP_INTERVAL =
        "templeton.zookeeper.cleanup.interval"; // 12 hours

    // The max age of a task allowed
    public static final String ZK_CLEANUP_MAX_AGE =
        "templeton.zookeeper.cleanup.maxage"; // ~ 1 week

    protected static long interval = 1000L * 60L * 60L * 12L;
    protected static long maxage = 1000L * 60L * 60L * 24L * 7L;

    // The logger
    private static final Log LOG = LogFactory.getLog(ZooKeeperCleanup.class);

    // Handle to cancel loop
    private boolean stop = false;

    // The instance
    private static ZooKeeperCleanup thisclass = null;

    // Whether the cycle is running
    private static boolean isRunning = false;

    /**
     * Create a cleanup object.  We use the appConfig to configure JobState.
     * @param appConf
     */
    private ZooKeeperCleanup(Configuration appConf) {
        this.appConf = appConf;
        interval = appConf.getLong(ZK_CLEANUP_INTERVAL, interval);
        maxage = appConf.getLong(ZK_CLEANUP_MAX_AGE, maxage);
    }

    public static ZooKeeperCleanup getInstance(Configuration appConf) {
        if (thisclass != null) {
            return thisclass;
        }
        thisclass = new ZooKeeperCleanup(appConf);
        return thisclass;
    }

    public static void startInstance(Configuration appConf) throws IOException {
        if (! isRunning) {
            getInstance(appConf).start();
        }
    }

    /**
     * Run the cleanup loop.
     *
     * @throws IOException
     */
    public void run() {
        ZooKeeper zk = null;
        List<String> nodes = null;
        isRunning = true;
        while (!stop) {
            try {
                // Put each check in a separate try/catch, so if that particular
                // cycle fails, it'll try again on the next cycle.
                try {
                    zk = ZooKeeperStorage.zkOpen(appConf);

                    nodes = getChildList(zk);

                    for (String node : nodes) {
                        boolean deleted = checkAndDelete(node, zk);
                        if (!deleted) {
                            break;
                        }
                    }

                    zk.close();
                } catch (Exception e) {
                    LOG.error("Cleanup cycle failed: " + e.getMessage());
                } finally {
                    if (zk != null) {
                        try {
                            zk.close();
                        } catch (InterruptedException e) {
                            // We're trying to exit anyway, just ignore.
                        }
                    }
                }

                long sleepMillis = (long) (Math.random() * interval);
                LOG.info("Next execution: " + new Date(new Date().getTime()
                                                       + sleepMillis));
                Thread.sleep(sleepMillis);

            } catch (Exception e) {
                // If sleep fails, we should exit now before things get worse.
                isRunning = false;
                LOG.error("Cleanup failed: " + e.getMessage(), e);
            }
        }
        isRunning = false;
    }

    /**
     * Get the list of jobs from JobState
     *
     * @throws IOException
     */
    public List<String> getChildList(ZooKeeper zk) {
        try {
            List<String> jobs = JobStateTracker.getTrackingJobs(appConf, zk);
            Collections.sort(jobs);
            return jobs;
        } catch (IOException e) {
            LOG.info("No jobs to check.");
        }
        return new ArrayList<String>();
    }

    /**
     * Check to see if a job is more than maxage old, and delete it if so.
     */
    public boolean checkAndDelete(String node, ZooKeeper zk) {
        JobState state = null;
        try {
            JobStateTracker tracker = new JobStateTracker(node, zk, true,
                    appConf.get(TempletonStorage.STORAGE_ROOT +
                            ZooKeeperStorage.TRACKINGDIR));
            long now = new Date().getTime();
            state = new JobState(tracker.getJobID(), appConf);

            // Set the default to 0 -- if the created date is null, there was
            // an error in creation, and we want to delete it anyway.
            long then = 0;
            if (state.getCreated() != null) {
                then = state.getCreated();
            }
            if (now - then > maxage) {
                LOG.info("Deleting " + tracker.getJobID());
                state.delete();
                tracker.delete();
                return true;
            }
            return false;
        } catch (Exception e) {
            LOG.info("checkAndDelete failed for " + node);
            // We don't throw a new exception for this -- just keep going with the
            // next one.
            return true;
        } finally {
            if (state != null) {
                try {
                    state.close();
                } catch (IOException e) {
                    LOG.info("Couldn't close job state.");
                }
            }
        }
    }

    // Handle to stop this process from the outside if needed.
    public void exit() {
        stop = true;
    }
}
