/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.descriptors.invalidation;

import java.util.*;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.descriptors.invalidation.CacheInvalidationPolicy;

/**
 * PUBLIC:
 * A CacheInvalidationPolicy that allows objects to expire every day at a specific time.
 * A daily cache invalidation policy is created with an hour, minute, second and millisecond
 * when objects will expire.  Objects will expire in the cache every day at that time.
 * @see CacheInvalidationPolicy
 */
public class DailyCacheInvalidationPolicy extends CacheInvalidationPolicy {
    protected Calendar expiryTime = null;
    protected Calendar previousExpiry = null;// previous expiry is stored for efficiency

    /**
     * INTERNAL:
     * Default constructor for Project XML
     * if setters are not called to set expiry times, expiry time will be the time of
     * day at which this object is instantiated.
     */
    public DailyCacheInvalidationPolicy() {
        expiryTime = Calendar.getInstance();
        previousExpiry = (Calendar)expiryTime.clone();
        previousExpiry.add(Calendar.DAY_OF_YEAR, -1);
    }

    /**
     * PUBLIC:
     * Construct a daily policy that will allow objects to expire at a specific time of day.
     * Provide the hour, minute, second and millisecond.  Objects that make use of this policy
     * will be set to expire at that exact time every day.
     */
    public DailyCacheInvalidationPolicy(int hour, int minute, int second, int millisecond) {
        setExpiryTime(hour, minute, second, millisecond);
    }

    /**
     * INTERNAL:
     * Return the next expiry time.
     */
    @Override
    public long getExpiryTimeInMillis(CacheKey key) {
        incrementExpiry();
        return this.expiryTime.getTimeInMillis();
    }

    /**
     * INTERNAL:
     * Get the expiry time as a Calendar.  Used for setting the expiry time in deployment XML
     */
    public Calendar getExpiryTime() {
        return expiryTime;
    }

    /**
     * INTERNAL:
     * Return true if this object has expire or is invalid
     */
    @Override
    public boolean isInvalidated(CacheKey key, long currentTimeMillis) {
        if (key.getInvalidationState() == CacheKey.CACHE_KEY_INVALID) {
            return true;
        }

        long expiryMillis = expiryTime.getTimeInMillis();
        long readTime = key.getReadTime();

        if (currentTimeMillis < expiryMillis) {
            long previousExpiryMillis = previousExpiry.getTimeInMillis();
            if (readTime >= previousExpiryMillis) {
                // both current time and read time are between expiry yesterday and expiry today - not expired
                return false;
            } else if (currentTimeMillis >= previousExpiryMillis) {
                // read time is less than previous expiry and current time is after it. - expired and need update of expiry
                return true;
            } else {
                // read time is before previous expiry and so is current time - strange case, but not expired
                return false;
            }
        } else {
            if (readTime < expiryMillis) {
                // current time is greater than expiry and read time is before - expire and update expiry
                incrementExpiry();
                return true;
            } else {
                // current time and read time are greater than expiry - no expire and update expiry
                incrementExpiry();
                return false;
            }
        }
    }

    /**
     * INTERNAL:
     * Update the expiry time to be the day after the current day.
     */
    public void incrementExpiry() {
        long currentTimeMillis = System.currentTimeMillis();
        long expiryInMillis = expiryTime.getTimeInMillis();
        if (currentTimeMillis <= expiryInMillis) {
            // no updated needed.  Return for efficiency
            return;
        }
        while (currentTimeMillis > expiryTime.getTimeInMillis()) {
            // increment the expiry time until it is after the current time
            previousExpiry.add(Calendar.DAY_OF_YEAR, 1);
            expiryTime.add(Calendar.DAY_OF_YEAR, 1);
        }
    }

    /**
     * PUBLIC:
     * Set a new expiry time for this object
    * Provide the hour, minute, second and millisecond.  Objects which make use of this policy
     * will be set to expire at that exact time every day.
     */
    public void setExpiryTime(int hour, int minute, int second, int millisecond) {
        expiryTime = Calendar.getInstance();
        expiryTime.set(Calendar.HOUR_OF_DAY, hour);
        expiryTime.set(Calendar.MINUTE, minute);
        expiryTime.set(Calendar.SECOND, second);
        expiryTime.set(Calendar.MILLISECOND, millisecond);
        previousExpiry = (Calendar)expiryTime.clone();
        previousExpiry.add(Calendar.DAY_OF_YEAR, -1);
        incrementExpiry();
    }

    /**
     * INTERNAL:
     * Set the expiry time based on a Calendar. Used for setting the expiry time from
     * deployment XML.
     */
    public void setExpiryTime(Calendar calendar) {
        setExpiryTime(calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND), calendar.get(Calendar.MILLISECOND));
    }

    @Override
    public Object clone() {
        DailyCacheInvalidationPolicy clone = null;

        try {
            clone = (DailyCacheInvalidationPolicy)super.clone();
            if (this.expiryTime != null) {
                clone.setExpiryTime((Calendar)this.expiryTime.clone());
            }
            if (this.previousExpiry != null) {
                clone.previousExpiry = (Calendar)this.previousExpiry.clone();
            }
        } catch (Exception exception) {
            throw new InternalError("clone failed");
        }

        return clone;
    }
}
