/*******************************************************************************
 * 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.ofbiz.service.calendar;

import java.util.ArrayList;
import com.ibm.icu.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.StringUtil;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.service.calendar.TemporalExpression;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;

/**
 * Recurrence Info Object
 */
public class RecurrenceInfo {

    public static final String module = RecurrenceInfo.class.getName();

    protected GenericValue info;
    protected Date startDate;
    protected List<RecurrenceRule> rRulesList;
    protected List<RecurrenceRule> eRulesList;
    protected List<Date> rDateList;
    protected List<Date> eDateList;

    /** Creates new RecurrenceInfo */
    public RecurrenceInfo(GenericValue info) throws RecurrenceInfoException {
        this.info = info;
        if (!info.getEntityName().equals("RecurrenceInfo"))
            throw new RecurrenceInfoException("Invalid RecurrenceInfo Value object.");
        init();
    }

    /** Initializes the rules for this RecurrenceInfo object. */
    public void init() throws RecurrenceInfoException {

        if (info.get("startDateTime") == null)
            throw new RecurrenceInfoException("Recurrence startDateTime cannot be null.");

        // Get start date
        long startTime = info.getTimestamp("startDateTime").getTime();

        if (startTime > 0) {
            int nanos = info.getTimestamp("startDateTime").getNanos();

            startTime += (nanos / 1000000);
        } else {
            throw new RecurrenceInfoException("Recurrence startDateTime must have a value.");
        }
        startDate = new Date(startTime);

        // Get the recurrence rules objects
        try {
            rRulesList = new ArrayList<RecurrenceRule>();
            for (GenericValue value: info.getRelated("RecurrenceRule", null, null, false)) {
                rRulesList.add(new RecurrenceRule(value));
            }
        } catch (GenericEntityException gee) {
            rRulesList = null;
        } catch (RecurrenceRuleException rre) {
            throw new RecurrenceInfoException("Illegal rule format.", rre);
        }

        // Get the exception rules objects
        try {
            eRulesList = new ArrayList<RecurrenceRule>();
            for (GenericValue value: info.getRelated("ExceptionRecurrenceRule", null, null, false)) {
                eRulesList.add(new RecurrenceRule(value));
            }
        } catch (GenericEntityException gee) {
            eRulesList = null;
        } catch (RecurrenceRuleException rre) {
            throw new RecurrenceInfoException("Illegal rule format", rre);
        }

        // Get the recurrence date list
        rDateList = RecurrenceUtil.parseDateList(StringUtil.split(info.getString("recurrenceDateTimes"), ","));
        // Get the exception date list
        eDateList = RecurrenceUtil.parseDateList(StringUtil.split(info.getString("exceptionDateTimes"), ","));

        // Sort the lists.
        Collections.sort(rDateList);
        Collections.sort(eDateList);
    }

    /** Returns the primary key for this value object */
    public String getID() {
        return info.getString("recurrenceInfoId");
    }

    /** Returns the startDate Date object. */
    public Date getStartDate() {
        return this.startDate;
    }

    /** Returns the long value of the startDate. */
    public long getStartTime() {
        return this.startDate.getTime();
    }

    /** Returns a recurrence rule iterator */
    public Iterator<RecurrenceRule> getRecurrenceRuleIterator() {
        return rRulesList.iterator();
    }

    /** Returns a sorted recurrence date iterator */
    public Iterator<Date> getRecurrenceDateIterator() {
        return rDateList.iterator();
    }

    /** Returns a exception recurrence iterator */
    public Iterator<RecurrenceRule> getExceptionRuleIterator() {
        return eRulesList.iterator();
    }

    /** Returns a sorted exception date iterator */
    public Iterator<Date> getExceptionDateIterator() {
        return eDateList.iterator();
    }

    /** Returns the current count of this recurrence. */
    public long getCurrentCount() {
        if (info.get("recurrenceCount") != null)
            return info.getLong("recurrenceCount").longValue();
        return 0;
    }

    /** Increments the current count of this recurrence and updates the record. */
    public void incrementCurrentCount() throws GenericEntityException {
        incrementCurrentCount(true);
    }

    /** Increments the current count of this recurrence. */
    public void incrementCurrentCount(boolean store) throws GenericEntityException {
        if (store) {
            info.set("recurrenceCount", getCurrentCount() + 1);
            info.store();
        }
    }

    /** Removes the recurrence from persistant store. */
    public void remove() throws RecurrenceInfoException {
        List<RecurrenceRule> rulesList = new ArrayList<RecurrenceRule>();

        rulesList.addAll(rRulesList);
        rulesList.addAll(eRulesList);

        try {
            for (RecurrenceRule rule: rulesList)
                rule.remove();
            info.remove();
        } catch (RecurrenceRuleException rre) {
            throw new RecurrenceInfoException(rre.getMessage(), rre);
        } catch (GenericEntityException gee) {
            throw new RecurrenceInfoException(gee.getMessage(), gee);
        }
    }

    /** Returns the first recurrence. */
    public long first() {
        return startDate.getTime();
        // First recurrence is always the start time
    }

    /** Returns the estimated last recurrence. */
    public long last() {
        // TODO: find the last recurrence.
        return 0;
    }

    /** Returns the next recurrence from now. */
    public long next() {
        return next(RecurrenceUtil.now());
    }

    /** Returns the next recurrence from the specified time. */
    public long next(long fromTime) {
        // Check for the first recurrence (StartTime is always the first recurrence)
        if (getCurrentCount() == 0 || fromTime == 0 || fromTime == startDate.getTime()) {
            return first();
        }

        if (Debug.verboseOn()) {
            Debug.logVerbose("Date List Size: " + (rDateList == null ? 0 : rDateList.size()), module);
            Debug.logVerbose("Rule List Size: " + (rRulesList == null ? 0 : rRulesList.size()), module);
        }

        // Check the rules and date list
        if (rDateList == null && rRulesList == null) {
            return 0;
        }

        long nextRuleTime = fromTime;
        boolean hasNext = true;

        // Get the next recurrence from the rule(s).
        Iterator<RecurrenceRule> rulesIterator = getRecurrenceRuleIterator();
        while (rulesIterator.hasNext()) {
            RecurrenceRule rule = rulesIterator.next();
            while (hasNext) {
                // Gets the next recurrence time from the rule.
                nextRuleTime = getNextTime(rule, nextRuleTime);
                // Tests the next recurrence against the rules.
                if (nextRuleTime == 0 || isValid(nextRuleTime)) {
                    hasNext = false;
                }
            }
        }
        return nextRuleTime;
    }

    /** Checks the current recurrence validity at the moment. */
    public boolean isValidCurrent() {
        return isValidCurrent(RecurrenceUtil.now());
    }

    /** Checks the current recurrence validity for checkTime. */
    public boolean isValidCurrent(long checkTime) {
        if (checkTime == 0 || (rDateList == null && rRulesList == null)) {
            return false;
        }

        boolean found = false;
        Iterator<RecurrenceRule> rulesIterator = getRecurrenceRuleIterator();
        while (rulesIterator.hasNext()) {
            RecurrenceRule rule = rulesIterator.next();
            long currentTime = rule.validCurrent(getStartTime(), checkTime, getCurrentCount());
            currentTime = checkDateList(rDateList, currentTime, checkTime);
            if ((currentTime > 0) && isValid(checkTime)) {
                found = true;
            } else {
                return false;
            }
        }

        return found;
    }

    private long getNextTime(RecurrenceRule rule, long fromTime) {
        long nextTime = rule.next(getStartTime(), fromTime, getCurrentCount());
        if (Debug.verboseOn()) Debug.logVerbose("Next Time Before Date Check: " + nextTime, module);
        return checkDateList(rDateList, nextTime, fromTime);
    }

    private long checkDateList(List<Date> dateList, long time, long fromTime) {
        long nextTime = time;

        if (UtilValidate.isNotEmpty(dateList)) {
            for (Date thisDate: dateList) {
                if (nextTime > 0 && thisDate.getTime() < nextTime && thisDate.getTime() > fromTime)
                    nextTime = thisDate.getTime();
                else if (nextTime == 0 && thisDate.getTime() > fromTime)
                    nextTime = thisDate.getTime();
            }
        }
        return nextTime;
    }

    private boolean isValid(long time) {
        Iterator<RecurrenceRule> exceptRulesIterator = getExceptionRuleIterator();

        while (exceptRulesIterator.hasNext()) {
            RecurrenceRule except = exceptRulesIterator.next();

            if (except.isValid(getStartTime(), time) || eDateList.contains(new Date(time)))
                return false;
        }
        return true;
    }

    public String primaryKey() {
        return info.getString("recurrenceInfoId");
    }

    public static RecurrenceInfo makeInfo(Delegator delegator, long startTime, int frequency,
            int interval, int count) throws RecurrenceInfoException {
        return makeInfo(delegator, startTime, frequency, interval, count, 0);
    }

    public static RecurrenceInfo makeInfo(Delegator delegator, long startTime, int frequency,
            int interval, long endTime) throws RecurrenceInfoException {
        return makeInfo(delegator, startTime, frequency, interval, -1, endTime);
    }

    public static RecurrenceInfo makeInfo(Delegator delegator, long startTime, int frequency,
            int interval, int count, long endTime) throws RecurrenceInfoException {
        try {
            RecurrenceRule r = RecurrenceRule.makeRule(delegator, frequency, interval, count, endTime);
            String ruleId = r.primaryKey();
            GenericValue value = delegator.makeValue("RecurrenceInfo");

            value.set("recurrenceRuleId", ruleId);
            value.set("startDateTime", new java.sql.Timestamp(startTime));
            delegator.createSetNextSeqId(value);
            RecurrenceInfo newInfo = new RecurrenceInfo(value);

            return newInfo;
        } catch (RecurrenceRuleException re) {
            throw new RecurrenceInfoException(re.getMessage(), re);
        } catch (GenericEntityException ee) {
            throw new RecurrenceInfoException(ee.getMessage(), ee);
        } catch (RecurrenceInfoException rie) {
            throw rie;
        }
    }

    /** Convert a RecurrenceInfo object to a TemporalExpression object.
     * @param info A RecurrenceInfo instance
     * @return A TemporalExpression instance
     */
    public static TemporalExpression toTemporalExpression(RecurrenceInfo info) {
        if (info == null) {
            throw new IllegalArgumentException("info argument cannot be null");
        }
        return new RecurrenceWrapper(info);
    }

    /** Wraps a RecurrenceInfo object with a TemporalExpression object. This
     * class is intended to help with the transition from RecurrenceInfo/RecurrenceRule
     * to TemporalExpression.
     */
    @SuppressWarnings("serial")
    protected static class RecurrenceWrapper extends TemporalExpression {
        protected RecurrenceInfo info;
        protected RecurrenceWrapper() {}
        public RecurrenceWrapper(RecurrenceInfo info) {
            this.info = info;
        }
        @Override
        public Calendar first(Calendar cal) {
            long result = this.info.first();
            if (result == 0) {
                return null;
            }
            Calendar first = (Calendar) cal.clone();
            first.setTimeInMillis(result);
            return first;
        }
        @Override
        public boolean includesDate(Calendar cal) {
            return this.info.isValidCurrent(cal.getTimeInMillis());
        }
        @Override
        public Calendar next(Calendar cal, ExpressionContext context) {
            long result = this.info.next(cal.getTimeInMillis());
            if (result == 0) {
                return null;
            }
            Calendar next = (Calendar) cal.clone();
            next.setTimeInMillis(result);
            return next;
        }
        @Override
        public void accept(TemporalExpressionVisitor visitor) {}
        @Override
        public boolean isSubstitutionCandidate(Calendar cal, TemporalExpression expressionToTest) {
            return false;
        }
    }
}
