// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
* Copyright (C) 2007-2013, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/basictz.h"
#include "gregoimp.h"
#include "uvector.h"
#include "cmemory.h"

U_NAMESPACE_BEGIN

#define MILLIS_PER_YEAR (365*24*60*60*1000.0)

BasicTimeZone::BasicTimeZone()
: TimeZone() {
}

BasicTimeZone::BasicTimeZone(const UnicodeString &id)
: TimeZone(id) {
}

BasicTimeZone::BasicTimeZone(const BasicTimeZone& source)
: TimeZone(source) {
}

BasicTimeZone::~BasicTimeZone() {
}

UBool
BasicTimeZone::hasEquivalentTransitions(const BasicTimeZone& tz, UDate start, UDate end,
                                        UBool ignoreDstAmount, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return FALSE;
    }
    if (hasSameRules(tz)) {
        return TRUE;
    }
    // Check the offsets at the start time
    int32_t raw1, raw2, dst1, dst2;
    getOffset(start, FALSE, raw1, dst1, status);
    if (U_FAILURE(status)) {
        return FALSE;
    }
    tz.getOffset(start, FALSE, raw2, dst2, status);
    if (U_FAILURE(status)) {
        return FALSE;
    }
    if (ignoreDstAmount) {
        if ((raw1 + dst1 != raw2 + dst2)
            || (dst1 != 0 && dst2 == 0)
            || (dst1 == 0 && dst2 != 0)) {
            return FALSE;
        }
    } else {
        if (raw1 != raw2 || dst1 != dst2) {
            return FALSE;
        }            
    }
    // Check transitions in the range
    UDate time = start;
    TimeZoneTransition tr1, tr2;
    while (TRUE) {
        UBool avail1 = getNextTransition(time, FALSE, tr1);
        UBool avail2 = tz.getNextTransition(time, FALSE, tr2);

        if (ignoreDstAmount) {
            // Skip a transition which only differ the amount of DST savings
            while (TRUE) {
                if (avail1
                        && tr1.getTime() <= end
                        && (tr1.getFrom()->getRawOffset() + tr1.getFrom()->getDSTSavings()
                                == tr1.getTo()->getRawOffset() + tr1.getTo()->getDSTSavings())
                        && (tr1.getFrom()->getDSTSavings() != 0 && tr1.getTo()->getDSTSavings() != 0)) {
                    getNextTransition(tr1.getTime(), FALSE, tr1);
                } else {
                    break;
                }
            }
            while (TRUE) {
                if (avail2
                        && tr2.getTime() <= end
                        && (tr2.getFrom()->getRawOffset() + tr2.getFrom()->getDSTSavings()
                                == tr2.getTo()->getRawOffset() + tr2.getTo()->getDSTSavings())
                        && (tr2.getFrom()->getDSTSavings() != 0 && tr2.getTo()->getDSTSavings() != 0)) {
                    tz.getNextTransition(tr2.getTime(), FALSE, tr2);
                } else {
                    break;
                }
            }
        }

        UBool inRange1 = (avail1 && tr1.getTime() <= end);
        UBool inRange2 = (avail2 && tr2.getTime() <= end);
        if (!inRange1 && !inRange2) {
            // No more transition in the range
            break;
        }
        if (!inRange1 || !inRange2) {
            return FALSE;
        }
        if (tr1.getTime() != tr2.getTime()) {
            return FALSE;
        }
        if (ignoreDstAmount) {
            if (tr1.getTo()->getRawOffset() + tr1.getTo()->getDSTSavings()
                        != tr2.getTo()->getRawOffset() + tr2.getTo()->getDSTSavings()
                    || (tr1.getTo()->getDSTSavings() != 0 &&  tr2.getTo()->getDSTSavings() == 0)
                    || (tr1.getTo()->getDSTSavings() == 0 &&  tr2.getTo()->getDSTSavings() != 0)) {
                return FALSE;
            }
        } else {
            if (tr1.getTo()->getRawOffset() != tr2.getTo()->getRawOffset() ||
                tr1.getTo()->getDSTSavings() != tr2.getTo()->getDSTSavings()) {
                return FALSE;
            }
        }
        time = tr1.getTime();
    }
    return TRUE;
}

void
BasicTimeZone::getSimpleRulesNear(UDate date, InitialTimeZoneRule*& initial,
        AnnualTimeZoneRule*& std, AnnualTimeZoneRule*& dst, UErrorCode& status) const {
    initial = NULL;
    std = NULL;
    dst = NULL;
    if (U_FAILURE(status)) {
        return;
    }
    int32_t initialRaw, initialDst;
    UnicodeString initialName;

    AnnualTimeZoneRule *ar1 = NULL;
    AnnualTimeZoneRule *ar2 = NULL;
    UnicodeString name;

    UBool avail;
    TimeZoneTransition tr;
    // Get the next transition
    avail = getNextTransition(date, FALSE, tr);
    if (avail) {
        tr.getFrom()->getName(initialName);
        initialRaw = tr.getFrom()->getRawOffset();
        initialDst = tr.getFrom()->getDSTSavings();

        // Check if the next transition is either DST->STD or STD->DST and
        // within roughly 1 year from the specified date
        UDate nextTransitionTime = tr.getTime();
        if (((tr.getFrom()->getDSTSavings() == 0 && tr.getTo()->getDSTSavings() != 0)
              || (tr.getFrom()->getDSTSavings() != 0 && tr.getTo()->getDSTSavings() == 0))
            && (date + MILLIS_PER_YEAR > nextTransitionTime)) {
 
            int32_t year, month, dom, dow, doy, mid;
            UDate d;

            // Get local wall time for the next transition time
            Grego::timeToFields(nextTransitionTime + initialRaw + initialDst,
                year, month, dom, dow, doy, mid);
            int32_t weekInMonth = Grego::dayOfWeekInMonth(year, month, dom);
            // Create DOW rule
            DateTimeRule *dtr = new DateTimeRule(month, weekInMonth, dow, mid, DateTimeRule::WALL_TIME);
            tr.getTo()->getName(name);

            // Note:  SimpleTimeZone does not support raw offset change.
            // So we always use raw offset of the given time for the rule,
            // even raw offset is changed.  This will result that the result
            // zone to return wrong offset after the transition.
            // When we encounter such case, we do not inspect next next
            // transition for another rule.
            ar1 = new AnnualTimeZoneRule(name, initialRaw, tr.getTo()->getDSTSavings(),
                dtr, year, AnnualTimeZoneRule::MAX_YEAR);

            if (tr.getTo()->getRawOffset() == initialRaw) {
                // Get the next next transition
                avail = getNextTransition(nextTransitionTime, FALSE, tr);
                if (avail) {
                    // Check if the next next transition is either DST->STD or STD->DST
                    // and within roughly 1 year from the next transition
                    if (((tr.getFrom()->getDSTSavings() == 0 && tr.getTo()->getDSTSavings() != 0)
                          || (tr.getFrom()->getDSTSavings() != 0 && tr.getTo()->getDSTSavings() == 0))
                         && nextTransitionTime + MILLIS_PER_YEAR > tr.getTime()) {

                        // Get local wall time for the next transition time
                        Grego::timeToFields(tr.getTime() + tr.getFrom()->getRawOffset() + tr.getFrom()->getDSTSavings(),
                            year, month, dom, dow, doy, mid);
                        weekInMonth = Grego::dayOfWeekInMonth(year, month, dom);
                        // Generate another DOW rule
                        dtr = new DateTimeRule(month, weekInMonth, dow, mid, DateTimeRule::WALL_TIME);
                        tr.getTo()->getName(name);
                        ar2 = new AnnualTimeZoneRule(name, tr.getTo()->getRawOffset(), tr.getTo()->getDSTSavings(),
                            dtr, year - 1, AnnualTimeZoneRule::MAX_YEAR);

                        // Make sure this rule can be applied to the specified date
                        avail = ar2->getPreviousStart(date, tr.getFrom()->getRawOffset(), tr.getFrom()->getDSTSavings(), TRUE, d);
                        if (!avail || d > date
                                || initialRaw != tr.getTo()->getRawOffset()
                                || initialDst != tr.getTo()->getDSTSavings()) {
                            // We cannot use this rule as the second transition rule
                            delete ar2;
                            ar2 = NULL;
                        }
                    }
                }
            }
            if (ar2 == NULL) {
                // Try previous transition
                avail = getPreviousTransition(date, TRUE, tr);
                if (avail) {
                    // Check if the previous transition is either DST->STD or STD->DST.
                    // The actual transition time does not matter here.
                    if ((tr.getFrom()->getDSTSavings() == 0 && tr.getTo()->getDSTSavings() != 0)
                        || (tr.getFrom()->getDSTSavings() != 0 && tr.getTo()->getDSTSavings() == 0)) {

                        // Generate another DOW rule
                        Grego::timeToFields(tr.getTime() + tr.getFrom()->getRawOffset() + tr.getFrom()->getDSTSavings(),
                            year, month, dom, dow, doy, mid);
                        weekInMonth = Grego::dayOfWeekInMonth(year, month, dom);
                        dtr = new DateTimeRule(month, weekInMonth, dow, mid, DateTimeRule::WALL_TIME);
                        tr.getTo()->getName(name);

                        // second rule raw/dst offsets should match raw/dst offsets
                        // at the given time
                        ar2 = new AnnualTimeZoneRule(name, initialRaw, initialDst,
                            dtr, ar1->getStartYear() - 1, AnnualTimeZoneRule::MAX_YEAR);

                        // Check if this rule start after the first rule after the specified date
                        avail = ar2->getNextStart(date, tr.getFrom()->getRawOffset(), tr.getFrom()->getDSTSavings(), FALSE, d);
                        if (!avail || d <= nextTransitionTime) {
                            // We cannot use this rule as the second transition rule
                            delete ar2;
                            ar2 = NULL;
                        }
                    }
                }
            }
            if (ar2 == NULL) {
                // Cannot find a good pair of AnnualTimeZoneRule
                delete ar1;
                ar1 = NULL;
            } else {
                // The initial rule should represent the rule before the previous transition
                ar1->getName(initialName);
                initialRaw = ar1->getRawOffset();
                initialDst = ar1->getDSTSavings();
            }
        }
    }
    else {
        // Try the previous one
        avail = getPreviousTransition(date, TRUE, tr);
        if (avail) {
            tr.getTo()->getName(initialName);
            initialRaw = tr.getTo()->getRawOffset();
            initialDst = tr.getTo()->getDSTSavings();
        } else {
            // No transitions in the past.  Just use the current offsets
            getOffset(date, FALSE, initialRaw, initialDst, status);
            if (U_FAILURE(status)) {
                return;
            }
        }
    }
    // Set the initial rule
    initial = new InitialTimeZoneRule(initialName, initialRaw, initialDst);

    // Set the standard and daylight saving rules
    if (ar1 != NULL && ar2 != NULL) {
        if (ar1->getDSTSavings() != 0) {
            dst = ar1;
            std = ar2;
        } else {
            std = ar1;
            dst = ar2;
        }
    }
}

void
BasicTimeZone::getTimeZoneRulesAfter(UDate start, InitialTimeZoneRule*& initial,
                                     UVector*& transitionRules, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }

    const InitialTimeZoneRule *orgini;
    TimeZoneTransition tzt;
    bool avail;
    int32_t ruleCount;
    TimeZoneRule *r = nullptr;
    UnicodeString name;
    int32_t i;
    UDate time, t;
    UDate firstStart;
    UBool bFinalStd = false, bFinalDst = false;

    initial = nullptr;
    transitionRules = nullptr;

    // Original transition rules
    ruleCount = countTransitionRules(status);
    if (U_FAILURE(status)) {
        return;
    }
    LocalPointer<UVector> orgRules(
        new UVector(uprv_deleteUObject, nullptr, ruleCount, status), status);
    if (U_FAILURE(status)) {
        return;
    }
    LocalMemory<const TimeZoneRule *> orgtrs(
        static_cast<const TimeZoneRule **>(uprv_malloc(sizeof(TimeZoneRule*)*ruleCount)));
    if (orgtrs.isNull()) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    getTimeZoneRules(orgini, &orgtrs[0], ruleCount, status);
    if (U_FAILURE(status)) {
        return;
    }
    for (i = 0; i < ruleCount; i++) {
        LocalPointer<TimeZoneRule> lpRule(orgtrs[i]->clone(), status);
        orgRules->adoptElement(lpRule.orphan(), status);
        if (U_FAILURE(status)) {
            return;
        }
    }

    avail = getPreviousTransition(start, TRUE, tzt);
    if (!avail) {
        // No need to filter out rules only applicable to time before the start
        initial = orgini->clone();
        if (initial == nullptr) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return;
        }
        transitionRules = orgRules.orphan();
        return;
    }

    LocalMemory<bool> done(static_cast<bool *>(uprv_malloc(sizeof(bool)*ruleCount)));
    if (done.isNull()) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    LocalPointer<UVector> filteredRules(
        new UVector(uprv_deleteUObject, nullptr, status), status);
    if (U_FAILURE(status)) {
        return;
    }

    // Create initial rule
    tzt.getTo()->getName(name);
    LocalPointer<InitialTimeZoneRule> res_initial(
        new InitialTimeZoneRule(name, tzt.getTo()->getRawOffset(), tzt.getTo()->getDSTSavings()), status);
    if (U_FAILURE(status)) {
        return;
    }

    // Mark rules which does not need to be processed
    for (i = 0; i < ruleCount; i++) {
        r = (TimeZoneRule*)orgRules->elementAt(i);
        avail = r->getNextStart(start, res_initial->getRawOffset(), res_initial->getDSTSavings(), FALSE, time);
        done[i] = !avail;
    }

    time = start;
    while (!bFinalStd || !bFinalDst) {
        avail = getNextTransition(time, FALSE, tzt);
        if (!avail) {
            break;
        }
        UDate updatedTime = tzt.getTime();
        if (updatedTime == time) {
            // Can get here if rules for start & end of daylight time have exactly
            // the same time.  
            // TODO:  fix getNextTransition() to prevent it?
            status = U_INVALID_STATE_ERROR;
            return;
        }
        time = updatedTime;
 
        const TimeZoneRule *toRule = tzt.getTo();
        for (i = 0; i < ruleCount; i++) {
            r = (TimeZoneRule*)orgRules->elementAt(i);
            if (*r == *toRule) {
                break;
            }
        }
        if (i >= ruleCount) {
            // This case should never happen
            status = U_INVALID_STATE_ERROR;
            return;
        }
        if (done[i]) {
            continue;
        }
        const TimeArrayTimeZoneRule *tar = dynamic_cast<const TimeArrayTimeZoneRule *>(toRule);
        const AnnualTimeZoneRule *ar;
        if (tar != NULL) {
            // Get the previous raw offset and DST savings before the very first start time
            TimeZoneTransition tzt0;
            t = start;
            while (TRUE) {
                avail = getNextTransition(t, FALSE, tzt0);
                if (!avail) {
                    break;
                }
                if (*(tzt0.getTo()) == *tar) {
                    break;
                }
                t = tzt0.getTime();
            }
            if (avail) {
                // Check if the entire start times to be added
                tar->getFirstStart(tzt.getFrom()->getRawOffset(), tzt.getFrom()->getDSTSavings(), firstStart);
                if (firstStart > start) {
                    // Just add the rule as is
                    LocalPointer<TimeArrayTimeZoneRule> lpTar(tar->clone(), status);
                    filteredRules->adoptElement(lpTar.orphan(), status);
                    if (U_FAILURE(status)) {
                        return;
                    }
                } else {
                    // Collect transitions after the start time
                    int32_t startTimes;
                    DateTimeRule::TimeRuleType timeType;
                    int32_t idx;

                    startTimes = tar->countStartTimes();
                    timeType = tar->getTimeType();
                    for (idx = 0; idx < startTimes; idx++) {
                        tar->getStartTimeAt(idx, t);
                        if (timeType == DateTimeRule::STANDARD_TIME) {
                            t -= tzt.getFrom()->getRawOffset();
                        }
                        if (timeType == DateTimeRule::WALL_TIME) {
                            t -= tzt.getFrom()->getDSTSavings();
                        }
                        if (t > start) {
                            break;
                        }
                    }
                    if (U_FAILURE(status)) {
                        return;
                    }
                    int32_t asize = startTimes - idx;
                    if (asize > 0) {
                        LocalMemory<UDate> newTimes(static_cast<UDate *>(uprv_malloc(sizeof(UDate) * asize)));
                        if (newTimes.isNull()) {
                            status = U_MEMORY_ALLOCATION_ERROR;
                            return;
                        }
                        for (int32_t newidx = 0; newidx < asize; newidx++) {
                            tar->getStartTimeAt(idx + newidx, newTimes[newidx]);
                        }
                        tar->getName(name);
                        LocalPointer<TimeArrayTimeZoneRule> newTar(new TimeArrayTimeZoneRule(
                                name, tar->getRawOffset(), tar->getDSTSavings(), &newTimes[0], asize, timeType), status);
                        filteredRules->adoptElement(newTar.orphan(), status);
                        if (U_FAILURE(status)) {
                            return;
                        }
                    }
                }
            }
        } else if ((ar = dynamic_cast<const AnnualTimeZoneRule *>(toRule)) != NULL) {
            ar->getFirstStart(tzt.getFrom()->getRawOffset(), tzt.getFrom()->getDSTSavings(), firstStart);
            if (firstStart == tzt.getTime()) {
                // Just add the rule as is
                LocalPointer<AnnualTimeZoneRule> arClone(ar->clone(), status);
                filteredRules->adoptElement(arClone.orphan(), status);
                if (U_FAILURE(status)) {
                    return;
                }
            } else {
                // Calculate the transition year
                int32_t year, month, dom, dow, doy, mid;
                Grego::timeToFields(tzt.getTime(), year, month, dom, dow, doy, mid);
                // Re-create the rule
                ar->getName(name);
                LocalPointer<AnnualTimeZoneRule> newAr(new AnnualTimeZoneRule(name, ar->getRawOffset(), ar->getDSTSavings(),
                    *(ar->getRule()), year, ar->getEndYear()), status);
                filteredRules->adoptElement(newAr.orphan(), status);
                if (U_FAILURE(status)) {
                    return;
                }
            }
            // check if this is a final rule
            if (ar->getEndYear() == AnnualTimeZoneRule::MAX_YEAR) {
                // After bot final standard and dst rules are processed,
                // exit this while loop.
                if (ar->getDSTSavings() == 0) {
                    bFinalStd = TRUE;
                } else {
                    bFinalDst = TRUE;
                }
            }
        }
        done[i] = true;
    }

    // Set the results
    initial = res_initial.orphan();
    transitionRules = filteredRules.orphan();
    return;
}

void
BasicTimeZone::getOffsetFromLocal(UDate /*date*/, UTimeZoneLocalOption /*nonExistingTimeOpt*/,
                                  UTimeZoneLocalOption /*duplicatedTimeOpt*/,
                                  int32_t& /*rawOffset*/, int32_t& /*dstOffset*/,
                                  UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    status = U_UNSUPPORTED_ERROR;
}

void BasicTimeZone::getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
                                       int32_t& rawOffset, int32_t& dstOffset,
                                       UErrorCode& status) const {
    getOffsetFromLocal(date, (UTimeZoneLocalOption)nonExistingTimeOpt,
                       (UTimeZoneLocalOption)duplicatedTimeOpt, rawOffset, dstOffset, status);
}

U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */

//eof
