/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2013 John Layt <jlayt@kde.org>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qtimezone.h"
#include "qtimezoneprivate_p.h"

#include "private/qcore_mac_p.h"
#include "qstringlist.h"

#include <Foundation/NSTimeZone.h>

#include <qdebug.h>

#include <algorithm>

QT_BEGIN_NAMESPACE

/*
    Private

    OS X system implementation
*/

// Create the system default time zone
QMacTimeZonePrivate::QMacTimeZonePrivate()
{
    // Reset the cached system tz then instantiate it:
    [NSTimeZone resetSystemTimeZone];
    m_nstz = [NSTimeZone.systemTimeZone retain];
    Q_ASSERT(m_nstz);
    m_id = QString::fromNSString(m_nstz.name).toUtf8();
}

// Create a named time zone
QMacTimeZonePrivate::QMacTimeZonePrivate(const QByteArray &ianaId)
    : m_nstz(nil)
{
    init(ianaId);
}

QMacTimeZonePrivate::QMacTimeZonePrivate(const QMacTimeZonePrivate &other)
    : QTimeZonePrivate(other), m_nstz([other.m_nstz copy])
{
}

QMacTimeZonePrivate::~QMacTimeZonePrivate()
{
    [m_nstz release];
}

QMacTimeZonePrivate *QMacTimeZonePrivate::clone() const
{
    return new QMacTimeZonePrivate(*this);
}

void QMacTimeZonePrivate::init(const QByteArray &ianaId)
{
    if (availableTimeZoneIds().contains(ianaId)) {
        m_nstz = [[NSTimeZone timeZoneWithName:QString::fromUtf8(ianaId).toNSString()] retain];
        if (m_nstz)
            m_id = ianaId;
    }
    if (!m_nstz) {
        // macOS has been seen returning a systemTimeZone which reports its name
        // as Asia/Kolkata, which doesn't appear in knownTimeZoneNames (which
        // calls the zone Asia/Calcutta). So explicitly check for the name
        // systemTimeZoneId() returns, and use systemTimeZone if we get it:
        m_nstz = [NSTimeZone.systemTimeZone retain];
        Q_ASSERT(m_nstz);
        if (QString::fromNSString(m_nstz.name).toUtf8() == ianaId)
            m_id = ianaId;
    }
}

QString QMacTimeZonePrivate::comment() const
{
    return QString::fromNSString(m_nstz.description);
}

QString QMacTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
                                         QTimeZone::NameType nameType,
                                         const QLocale &locale) const
{
    // TODO Mac doesn't support OffsetName yet so use standard offset name
    if (nameType == QTimeZone::OffsetName) {
        const Data nowData = data(QDateTime::currentMSecsSinceEpoch());
        // TODO Cheat for now, assume if has dst the offset if 1 hour
        if (timeType == QTimeZone::DaylightTime && hasDaylightTime())
            return isoOffsetFormat(nowData.standardTimeOffset + 3600);
        else
            return isoOffsetFormat(nowData.standardTimeOffset);
    }

    NSTimeZoneNameStyle style = NSTimeZoneNameStyleStandard;

    switch (nameType) {
    case QTimeZone::ShortName :
        if (timeType == QTimeZone::DaylightTime)
            style = NSTimeZoneNameStyleShortDaylightSaving;
        else if (timeType == QTimeZone::GenericTime)
            style = NSTimeZoneNameStyleShortGeneric;
        else
            style = NSTimeZoneNameStyleShortStandard;
        break;
    case QTimeZone::DefaultName :
    case QTimeZone::LongName :
        if (timeType == QTimeZone::DaylightTime)
            style = NSTimeZoneNameStyleDaylightSaving;
        else if (timeType == QTimeZone::GenericTime)
            style = NSTimeZoneNameStyleGeneric;
        else
            style = NSTimeZoneNameStyleStandard;
        break;
    case QTimeZone::OffsetName :
        // Unreachable
        break;
    }

    NSString *macLocaleCode = locale.name().toNSString();
    NSLocale *macLocale = [[NSLocale alloc] initWithLocaleIdentifier:macLocaleCode];
    const QString result = QString::fromNSString([m_nstz localizedName:style locale:macLocale]);
    [macLocale release];
    return result;
}

QString QMacTimeZonePrivate::abbreviation(qint64 atMSecsSinceEpoch) const
{
    const NSTimeInterval seconds = atMSecsSinceEpoch / 1000.0;
    return QString::fromNSString([m_nstz abbreviationForDate:[NSDate dateWithTimeIntervalSince1970:seconds]]);
}

int QMacTimeZonePrivate::offsetFromUtc(qint64 atMSecsSinceEpoch) const
{
    const NSTimeInterval seconds = atMSecsSinceEpoch / 1000.0;
    return [m_nstz secondsFromGMTForDate:[NSDate dateWithTimeIntervalSince1970:seconds]];
}

int QMacTimeZonePrivate::standardTimeOffset(qint64 atMSecsSinceEpoch) const
{
    return offsetFromUtc(atMSecsSinceEpoch) - daylightTimeOffset(atMSecsSinceEpoch);
}

int QMacTimeZonePrivate::daylightTimeOffset(qint64 atMSecsSinceEpoch) const
{
    const NSTimeInterval seconds = atMSecsSinceEpoch / 1000.0;
    return [m_nstz daylightSavingTimeOffsetForDate:[NSDate dateWithTimeIntervalSince1970:seconds]];
}

bool QMacTimeZonePrivate::hasDaylightTime() const
{
    // TODO No Mac API, assume if has transitions
    return hasTransitions();
}

bool QMacTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const
{
    const NSTimeInterval seconds = atMSecsSinceEpoch / 1000.0;
    return [m_nstz isDaylightSavingTimeForDate:[NSDate dateWithTimeIntervalSince1970:seconds]];
}

QTimeZonePrivate::Data QMacTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
{
    const NSTimeInterval seconds = forMSecsSinceEpoch / 1000.0;
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:seconds];
    Data data;
    data.atMSecsSinceEpoch = forMSecsSinceEpoch;
    data.offsetFromUtc = [m_nstz secondsFromGMTForDate:date];
    data.daylightTimeOffset = [m_nstz daylightSavingTimeOffsetForDate:date];
    data.standardTimeOffset = data.offsetFromUtc - data.daylightTimeOffset;
    data.abbreviation = QString::fromNSString([m_nstz abbreviationForDate:date]);
    return data;
}

bool QMacTimeZonePrivate::hasTransitions() const
{
    // TODO No direct Mac API, so return if has next after 1970, i.e. since start of tz
    // TODO Not sure what is returned in event of no transitions, assume will be before requested date
    NSDate *epoch = [NSDate dateWithTimeIntervalSince1970:0];
    const NSDate *date = [m_nstz nextDaylightSavingTimeTransitionAfterDate:epoch];
    const bool result = (date.timeIntervalSince1970 > epoch.timeIntervalSince1970);
    return result;
}

QTimeZonePrivate::Data QMacTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch) const
{
    QTimeZonePrivate::Data tran;
    const NSTimeInterval seconds = afterMSecsSinceEpoch / 1000.0;
    NSDate *nextDate = [NSDate dateWithTimeIntervalSince1970:seconds];
    nextDate = [m_nstz nextDaylightSavingTimeTransitionAfterDate:nextDate];
    const NSTimeInterval nextSecs = nextDate.timeIntervalSince1970;
    if (nextDate == nil || nextSecs <= seconds) {
        [nextDate release];
        return invalidData();
    }
    tran.atMSecsSinceEpoch = nextSecs * 1000;
    tran.offsetFromUtc = [m_nstz secondsFromGMTForDate:nextDate];
    tran.daylightTimeOffset = [m_nstz daylightSavingTimeOffsetForDate:nextDate];
    tran.standardTimeOffset = tran.offsetFromUtc - tran.daylightTimeOffset;
    tran.abbreviation = QString::fromNSString([m_nstz abbreviationForDate:nextDate]);
    return tran;
}

QTimeZonePrivate::Data QMacTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const
{
    // The native API only lets us search forward, so we need to find an early-enough start:
    const NSTimeInterval lowerBound = std::numeric_limits<NSTimeInterval>::lowest();
    const qint64 endSecs = beforeMSecsSinceEpoch / 1000;
    const int year = 366 * 24 * 3600; // a (long) year, in seconds
    NSTimeInterval prevSecs = endSecs; // sentinel for later check
    NSTimeInterval nextSecs = prevSecs - year;
    NSTimeInterval tranSecs = lowerBound; // time at a transition; may be > endSecs

    NSDate *nextDate = [NSDate dateWithTimeIntervalSince1970:nextSecs];
    nextDate = [m_nstz nextDaylightSavingTimeTransitionAfterDate:nextDate];
    if (nextDate != nil
        && (tranSecs = nextDate.timeIntervalSince1970) < endSecs) {
        // There's a transition within the last year before endSecs:
        nextSecs = tranSecs;
    } else {
        // Need to start our search earlier:
        nextDate = [NSDate dateWithTimeIntervalSince1970:lowerBound];
        nextDate = [m_nstz nextDaylightSavingTimeTransitionAfterDate:nextDate];
        if (nextDate != nil) {
            NSTimeInterval lateSecs = nextSecs;
            nextSecs = nextDate.timeIntervalSince1970;
            Q_ASSERT(nextSecs <= endSecs - year || nextSecs == tranSecs);
            /*
              We're looking at the first ever transition for our zone, at
              nextSecs (and our zone *does* have at least one transition).  If
              it's later than endSecs - year, then we must have found it on the
              initial check and therefore set tranSecs to the same transition
              time (which, we can infer here, is >= endSecs).  In this case, we
              won't enter the binary-chop loop, below.

              In the loop, nextSecs < lateSecs < endSecs: we have a transition
              at nextSecs and there is no transition between lateSecs and
              endSecs.  The loop narrows the interval between nextSecs and
              lateSecs by looking for a transition after their mid-point; if it
              finds one < endSecs, nextSecs moves to this transition; otherwise,
              lateSecs moves to the mid-point.  This soon enough narrows the gap
              to within a year, after which walking forward one transition at a
              time (the "Wind through" loop, below) is good enough.
            */

            // Binary chop to within a year of last transition before endSecs:
            while (nextSecs + year < lateSecs) {
                // Careful about overflow, not fussy about rounding errors:
                NSTimeInterval middle = nextSecs / 2 + lateSecs / 2;
                NSDate *split = [NSDate dateWithTimeIntervalSince1970:middle];
                split = [m_nstz nextDaylightSavingTimeTransitionAfterDate:split];
                if (split != nil && (tranSecs = split.timeIntervalSince1970) < endSecs) {
                    nextDate = split;
                    nextSecs = tranSecs;
                } else {
                    lateSecs = middle;
                }
            }
            Q_ASSERT(nextDate != nil);
            // ... and nextSecs < endSecs unless first transition ever was >= endSecs.
        } // else: we have no data - prevSecs is still endSecs, nextDate is still nil
    }
    // Either nextDate is nil or nextSecs is at its transition.

    // Wind through remaining transitions (spanning at most a year), one at a time:
    while (nextDate != nil && nextSecs < endSecs) {
        prevSecs = nextSecs;
        nextDate = [m_nstz nextDaylightSavingTimeTransitionAfterDate:nextDate];
        nextSecs = nextDate.timeIntervalSince1970;
        if (nextSecs <= prevSecs) // presumably no later data available
            break;
    }
    if (prevSecs < endSecs) // i.e. we did make it into that while loop
        return data(qint64(prevSecs * 1e3));

    // No transition data; or first transition later than requested time.
    return invalidData();
}

QByteArray QMacTimeZonePrivate::systemTimeZoneId() const
{
    // Reset the cached system tz then return the name
    [NSTimeZone resetSystemTimeZone];
    Q_ASSERT(NSTimeZone.systemTimeZone);
    return QString::fromNSString(NSTimeZone.systemTimeZone.name).toUtf8();
}

QList<QByteArray> QMacTimeZonePrivate::availableTimeZoneIds() const
{
    NSEnumerator *enumerator = NSTimeZone.knownTimeZoneNames.objectEnumerator;
    QByteArray tzid = QString::fromNSString(enumerator.nextObject).toUtf8();

    QList<QByteArray> list;
    while (!tzid.isEmpty()) {
        list << tzid;
        tzid = QString::fromNSString(enumerator.nextObject).toUtf8();
    }

    std::sort(list.begin(), list.end());
    list.erase(std::unique(list.begin(), list.end()), list.end());

    return list;
}

NSTimeZone *QMacTimeZonePrivate::nsTimeZone() const
{
    return m_nstz;
}

QT_END_NAMESPACE
