/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtXmlPatterns 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 <QStringList>
#if QT_CONFIG(timezone)
#include <QTimeZone>
#endif

#include "qbuiltintypes_p.h"
#include "qitem_p.h"
#include "qpatternistlocale_p.h"
#include "qvalidationerror_p.h"

#include "qabstractdatetime_p.h"

QT_BEGIN_NAMESPACE

using namespace QPatternist;

AbstractDateTime::AbstractDateTime(const QDateTime &dateTime) : m_dateTime(dateTime)
{
    Q_ASSERT(dateTime.isValid());
}

#define badData(msg)        errorMessage = ValidationError::createError(msg); return QDateTime()
#define getCapt(sym)        ((captTable.sym == -1) ? QString() : capts.at(captTable.sym))
#define getSafeCapt(sym)    ((captTable.sym == -1) ? QString() : capts.value(captTable.sym))

QDateTime AbstractDateTime::create(AtomicValue::Ptr &errorMessage,
                                   const QString &lexicalSource,
                                   const CaptureTable &captTable)
{
    QRegExp myExp(captTable.regExp);

    if(!myExp.exactMatch(lexicalSource))
    {
        badData(QString());
    }

    const QStringList capts(myExp.capturedTexts());
    const QString yearStr(getCapt(year));

    if(yearStr.size() > 4 && yearStr.at(0) == QLatin1Char('0'))
    {
        badData(QtXmlPatterns::tr("Year %1 is invalid because it begins with %2.")
                .arg(formatData(yearStr)).arg(formatData("0")));
    }

    /* If the strings are empty, load default values which are
     * guranteed to pass the validness tests. */
    const QString monthStr(getCapt(month));
    const QString dayStr(getCapt(day));
    YearProperty year = yearStr.isEmpty() ? DefaultYear : yearStr.toInt();
    if(getCapt(yearSign) == QChar::fromLatin1('-'))
        year = -year;
    const MonthProperty month = monthStr.isEmpty() ? DefaultMonth : monthStr.toInt();
    const MonthProperty day = dayStr.isEmpty() ? DefaultDay : dayStr.toInt();

    if(!QDate::isValid(year, month, day))
    {
        /* Try to give an intelligent message. */
        if(day > 31 || day < 1)
        {
            badData(QtXmlPatterns::tr("Day %1 is outside the range %2..%3.")
                    .arg(formatData(QString::number(day)))
                    .arg(formatData("01"))
                    .arg(formatData("31")));
        }
        else if(month > 12 || month < -12 || month == 0)
        {
            badData(QtXmlPatterns::tr("Month %1 is outside the range %2..%3.")
                    .arg(month)
                    .arg(formatData("01"))
                    .arg(formatData("12")));

        }
        else if(QDate::isValid(DefaultYear, month, day))
        {
            /* We can't use the badData() macro here because we need a different
             * error code: FODT0001 instead of FORG0001. */
            errorMessage = ValidationError::createError(QtXmlPatterns::tr(
                               "Overflow: Can't represent date %1.")
                               .arg(formatData(QLatin1String("%1-%2-%3"))
                                    .arg(year).arg(month).arg(day)),
                               ReportContext::FODT0001);
            return QDateTime();
        }
        else
        {
            badData(QtXmlPatterns::tr("Day %1 is invalid for month %2.")
                         .arg(formatData(QString::number(day)))
                         .arg(formatData(QString::number(month))));
        }
    }

    /* Parse the zone offset. */
    ZoneOffsetParseResult zoResult;
    const ZOTotal offset = parseZoneOffset(zoResult, capts, captTable);

    if(zoResult == Error)
    {
        errorMessage = ValidationError::createError();
        /* We encountered an error, so stop processing. */
        return QDateTime();
    }

    QDate date(year, month, day);

    /* Only deal with time if time is needed. */
    if(captTable.hour == -1)
    {
        QDateTime result = date.startOfDay();
        setUtcOffset(result, zoResult, offset);
        return result;
    }
    else
    {
        /* Now, it's time for the time-part.
         *
         * If the strings are empty, toInt() will return 0, which
         * in all cases is valid properties. */
        const QString hourStr(getCapt(hour));
        const QString minutesStr(getCapt(minutes));
        const QString secondsStr(getCapt(seconds));
        HourProperty hour = hourStr.toInt();
        const MinuteProperty mins = minutesStr.toInt();
        const SecondProperty secs = secondsStr.toInt();

        QString msecondsStr(getSafeCapt(mseconds));
        if(!msecondsStr.isEmpty())
            msecondsStr = msecondsStr.leftJustified(3, QLatin1Char('0'), true);
        const MSecondProperty msecs = msecondsStr.toInt();

        if(hour == 24)
        {
            /* 24:00:00.00 is an invalid time for QTime, so handle it here. */
            if(mins != 0 || secs != 0 || msecs != 0)
            {
                badData(QtXmlPatterns::tr("Time 24:%1:%2.%3 is invalid. "
                                          "Hour is 24, but minutes, seconds, "
                                          "and milliseconds are not all 0; ")
                        .arg(mins).arg(secs).arg(msecs));
            }
            else
            {
                hour = 0;
                date = date.addDays(1);
            }
        }
        else if(!QTime::isValid(hour, mins, secs, msecs))
        {
            badData(QtXmlPatterns::tr("Time %1:%2:%3.%4 is invalid.")
                         .arg(hour).arg(mins).arg(secs).arg(msecs));
        }

        const QTime time(hour, mins, secs, msecs);
        Q_ASSERT(time.isValid());

        QDateTime result(date, time);
        setUtcOffset(result, zoResult, offset);
        return result;
    }
}

ZOTotal AbstractDateTime::parseZoneOffset(ZoneOffsetParseResult &result,
                                          const QStringList &capts,
                                          const CaptureTable &captTable)
{
    const QString zoneOffsetSignStr(getCapt(zoneOffsetSign));

    if(zoneOffsetSignStr.isEmpty())
    {
        const QString zoneOffsetUTCStr(getCapt(zoneOffsetUTCSymbol));
        Q_ASSERT(zoneOffsetUTCStr.isEmpty() || zoneOffsetUTCStr == QLatin1String("Z"));

        if(zoneOffsetUTCStr.isEmpty())
            result = LocalTime;
        else
            result = UTC;

        return 0;
    }

    Q_ASSERT(zoneOffsetSignStr == QLatin1String("-") || zoneOffsetSignStr == QLatin1String("+"));

    const QString zoneOffsetHourStr(getCapt(zoneOffsetHour));
    Q_ASSERT(!zoneOffsetHourStr.isEmpty());
    const ZOHourProperty zoHour = zoneOffsetHourStr.toInt();

    if(zoHour > 14 || zoHour < -14)
    {
        result = Error;
        return 0;
        /*
        badZOData(QtXmlPatterns::tr("%1 it is not a valid hour property in a zone offset. "
                       "It must be less than or equal to 14.").arg(zoHour));
                       */
    }

    const QString zoneOffsetMinuteStr(getCapt(zoneOffsetMinute));
    Q_ASSERT(!zoneOffsetMinuteStr.isEmpty());
    const ZOHourProperty zoMins = zoneOffsetMinuteStr.toInt();

    if(zoHour == 14 && zoMins != 0)
    {
        /*
        badZOData(QtXmlPatterns::tr("When the hour property in a zone offset is 14, the minute property "
                       "must be 0, not %1.").arg(zoMins));
                       */
        result = Error;
        return 0;
    }
    else if(zoMins > 59 || zoMins < -59)
    {
        /*
        badZOData(QtXmlPatterns::tr("The minute property in a zone offset cannot be larger than 59. "
                       "%1 is therefore invalid.").arg(zoMins));
                       */
        result = Error;
        return 0;
    }

    if(zoHour == 0 && zoMins == 0) /* "-00:00" and "+00:00" is equal to 'Z'. */
    {
        result = UTC;
        return 0;
    }
    else
    {
        ZOTotal zoneOffset = (zoHour * 60 + zoMins) * 60;

        if(zoneOffsetSignStr == QChar::fromLatin1('-'))
            zoneOffset = -zoneOffset;

        result = Offset;
        return zoneOffset;
    }
}
//#undef badZOData

void AbstractDateTime::setUtcOffset(QDateTime &result,
                                     const ZoneOffsetParseResult zoResult,
                                     const int zoOffset)
{
    if(zoResult == UTC)
        result.setTimeSpec(Qt::UTC);
    else if(zoResult == LocalTime)
        result.setTimeSpec(Qt::LocalTime);
    else
    {
        Q_ASSERT(zoResult == Offset);
        result.setOffsetFromUtc(zoOffset);
    }
}

#undef badData
#undef getCapt
#undef getSafeCapt

bool AbstractDateTime::isRangeValid(const QDate &date,
                                    QString &message)
{
    if(date.isValid())
        return true;
    else
    {
        message = QtXmlPatterns::tr("Overflow: Date can't be represented.");
        return false;
    }
}

QString AbstractDateTime::dateToString() const
{
    return m_dateTime.toString(QLatin1String("yyyy-MM-dd"));
}

QString AbstractDateTime::serializeMSeconds(const MSecondProperty mseconds)
{
    QString retval;
    retval.append(QLatin1Char('.'));
    int div = 100;
    MSecondProperty msecs = mseconds;

    while(msecs > 0)
    {
        int d = msecs / div;
        retval.append(QLatin1Char(d + '0'));
        msecs = msecs % div;
        div = div / 10;
    }

    return retval;
}

QString AbstractDateTime::timeToString() const
{
    QString base(m_dateTime.toString(QLatin1String("hh:mm:ss")));
    const MSecondProperty msecs = m_dateTime.time().msec();

    if(msecs)
        base.append(serializeMSeconds(msecs));

    return base;
}

QString AbstractDateTime::zoneOffsetToString() const
{
    switch(m_dateTime.timeSpec())
    {
        case Qt::LocalTime:
            return QString();
        case Qt::UTC:
            return QLatin1String("Z");
        default:
        {
            Q_ASSERT(m_dateTime.timeSpec() == Qt::OffsetFromUTC);

            const int zoneOffset = m_dateTime.offsetFromUtc();
            Q_ASSERT(zoneOffset != 0);
            const int posZoneOffset = qAbs(zoneOffset);

            /* zoneOffset is in seconds. */
            const int hours = posZoneOffset/(60 * 60);
            const int minutes = (posZoneOffset % (60 * 60)) / 60;

            QString result;
            result.reserve(6);

            result.append(zoneOffset < 0 ? QLatin1Char('-') : QLatin1Char('+'));
            result.append(QString::number(hours).rightJustified(2, QLatin1Char('0')));
            result.append(QLatin1Char(':'));
            result.append(QString::number(minutes).rightJustified(2, QLatin1Char('0')));
            return result;
        }
    }
}

void AbstractDateTime::copyTimeSpec(const QDateTime &from,
                                    QDateTime &to)
{
    switch(from.timeSpec())
    {
        case Qt::UTC:
        /* Fallthrough. */
        case Qt::LocalTime:
        {
            to.setTimeSpec(from.timeSpec());
            return;
        }
        case Qt::OffsetFromUTC:
        {
            to.setOffsetFromUtc(from.offsetFromUtc());
            Q_ASSERT(to.timeSpec() == Qt::OffsetFromUTC);
            return;
        }
#if QT_CONFIG(timezone)
        case Qt::TimeZone:
        {
            to.setTimeZone(from.timeZone());
            return;
        }
#endif
    }
}

Item AbstractDateTime::fromValue(const QDateTime &) const
{
    Q_ASSERT_X(false, Q_FUNC_INFO,
               "Calling AbstractDateTime::fromDateTime() makes no sense.");
    return Item();
}
QT_END_NAMESPACE
