/****************************************************************************
**
** 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 "qbuiltintypes_p.h"
#include "qcommonsequencetypes_p.h"
#include "qcommonvalues_p.h"
#include "qdistinctiterator_p.h"
#include "qebvextractor_p.h"
#include "qemptysequence_p.h"
#include "qgenericsequencetype_p.h"
#include "qindexofiterator_p.h"
#include "qinsertioniterator_p.h"
#include "qinteger_p.h"
#include "qremovaliterator_p.h"
#include "qsequencegeneratingfns_p.h"
#include "qsubsequenceiterator_p.h"

#include "qsequencefns_p.h"

QT_BEGIN_NAMESPACE

using namespace QPatternist;

bool BooleanFN::evaluateEBV(const DynamicContext::Ptr &context) const
{
    return m_operands.first()->evaluateEBV(context);
}

Expression::Ptr BooleanFN::typeCheck(const StaticContext::Ptr &context,
                                     const SequenceType::Ptr &reqType)
{
    return EBVExtractor::typeCheck<FunctionCall>(context, reqType, this);
}

Item::Iterator::Ptr IndexOfFN::evaluateSequence(const DynamicContext::Ptr &context) const
{
    return Item::Iterator::Ptr(new IndexOfIterator(m_operands.first()->evaluateSequence(context),
                                                   m_operands.at(1)->evaluateSingleton(context),
                                                   comparator(), context,
                                                   ConstPtr(this)));
}

Expression::Ptr IndexOfFN::typeCheck(const StaticContext::Ptr &context,
                                     const SequenceType::Ptr &reqType)
{
    const Expression::Ptr me(FunctionCall::typeCheck(context, reqType));
    const ItemType::Ptr t1(m_operands.first()->staticType()->itemType());
    const ItemType::Ptr t2(m_operands.at(1)->staticType()->itemType());

    if(*CommonSequenceTypes::Empty == *t1 ||
       *CommonSequenceTypes::Empty == *t2)
    {
        return EmptySequence::create(this, context);
    }
    else
    {
        prepareComparison(fetchComparator(t1, t2, context));
        return me;
    }
}

Item::Iterator::Ptr DistinctValuesFN::evaluateSequence(const DynamicContext::Ptr &context) const
{
    return Item::Iterator::Ptr(new DistinctIterator(m_operands.first()->evaluateSequence(context),
                                                    comparator(),
                                                    ConstPtr(this),
                                                    context));
}

Expression::Ptr DistinctValuesFN::typeCheck(const StaticContext::Ptr &context,
                                            const SequenceType::Ptr &reqType)
{
    const Expression::Ptr me(FunctionCall::typeCheck(context, reqType));
    const ItemType::Ptr t1(m_operands.first()->staticType()->itemType());

    if(*CommonSequenceTypes::Empty == *t1)
        return EmptySequence::create(this, context);
    else if(!m_operands.first()->staticType()->cardinality().allowsMany())
        return m_operands.first();
    else if(BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t1))
        return me;
    else
    {
        prepareComparison(fetchComparator(t1, t1, context));
        return me;
    }
}

SequenceType::Ptr DistinctValuesFN::staticType() const
{
    const SequenceType::Ptr t(m_operands.first()->staticType());
    return makeGenericSequenceType(t->itemType(),
                                   t->cardinality().allowsMany() ? Cardinality::oneOrMore()
                                                                 : Cardinality::exactlyOne());
}

Item::Iterator::Ptr InsertBeforeFN::evaluateSequence(const DynamicContext::Ptr &context) const
{
    const Item::Iterator::Ptr target(m_operands.first()->evaluateSequence(context));
    const Item::Iterator::Ptr inserts(m_operands.at(2)->evaluateSequence(context));

    xsInteger position = m_operands.at(1)->evaluateSingleton(context).as<Numeric>()->toInteger();

    if(position < 1)
        position = 1;

    return Item::Iterator::Ptr(new InsertionIterator(target, position, inserts));
}

Item InsertBeforeFN::evaluateSingleton(const DynamicContext::Ptr &context) const
{
    return evaluateSequence(context)->next();
}

SequenceType::Ptr InsertBeforeFN::staticType() const
{
    const SequenceType::Ptr t1(m_operands.first()->staticType());
    const SequenceType::Ptr t2(m_operands.last()->staticType());

    return makeGenericSequenceType(t1->itemType() | t2->itemType(),
                                   t1->cardinality() + t2->cardinality());
}

Item::Iterator::Ptr RemoveFN::evaluateSequence(const DynamicContext::Ptr &context) const
{
    const xsInteger pos = m_operands.last()->evaluateSingleton(context).as<Numeric>()->toInteger();
    Item::Iterator::Ptr it(m_operands.first()->evaluateSequence(context));

    if(pos < 1)
        return it;

    return Item::Iterator::Ptr(new RemovalIterator(it, pos));
}

Item RemoveFN::evaluateSingleton(const DynamicContext::Ptr &context) const
{
    const xsInteger pos = m_operands.last()->evaluateSingleton(context).as<Numeric>()->toInteger();
    if(pos <= 1)
        return Item();

    return m_operands.first()->evaluateSingleton(context);
}

SequenceType::Ptr RemoveFN::staticType() const
{
    const SequenceType::Ptr opType(m_operands.first()->staticType());
    const Cardinality c(opType->cardinality());

    if(c.minimum() == 0)
        return makeGenericSequenceType(opType->itemType(), c);
    else
    {
        return makeGenericSequenceType(opType->itemType(),
                                       Cardinality::fromRange(c.minimum() - 1,
                                                              c.maximum()));
    }
}

Item::Iterator::Ptr ReverseFN::evaluateSequence(const DynamicContext::Ptr &context) const
{
    return m_operands.first()->evaluateSequence(context)->toReversed();
}

Expression::Ptr ReverseFN::typeCheck(const StaticContext::Ptr &context,
                                     const SequenceType::Ptr &reqType)
{
    if(m_operands.first()->staticType()->cardinality().allowsMany())
        return FunctionCall::typeCheck(context, reqType);
    else
        return m_operands.first()->typeCheck(context, reqType);
}

SequenceType::Ptr ReverseFN::staticType() const
{
    return m_operands.first()->staticType();
}

SubsequenceFN::SubsequenceFN() : m_hasTypeChecked(false)
{
}

Expression::Ptr SubsequenceFN::typeCheck(const StaticContext::Ptr &context,
                                         const SequenceType::Ptr &reqType)
{
    m_hasTypeChecked = true;
    return FunctionCall::typeCheck(context, reqType);
}

Item::Iterator::Ptr SubsequenceFN::evaluateSequence(const DynamicContext::Ptr &context) const
{
    Item::Iterator::Ptr it(m_operands.first()->evaluateSequence(context));

    xsInteger startingLoc = m_operands.at(1)->evaluateSingleton(context).as<Numeric>()->round()->toInteger();
    xsInteger length = -1;

    if(m_operands.count() == 3)
    {
        length = m_operands.last()->evaluateSingleton(context).as<Numeric>()->toInteger();

        if(startingLoc + length < 1 || (startingLoc > (startingLoc + length)))
            return CommonValues::emptyIterator;
    }

    /* F&O, 15.1.10, "If $startingLoc is zero or negative, the
     * subsequence includes items from the beginning of the $sourceSeq." */
    if(startingLoc < 1)
        startingLoc = 1;

    if(length < 1 && length != -1)
        return CommonValues::emptyIterator;
    return Item::Iterator::Ptr(new SubsequenceIterator(it, startingLoc, length));
}

Item SubsequenceFN::evaluateSingleton(const DynamicContext::Ptr &context) const
{
    return evaluateSequence(context)->next();
}

Expression::Ptr SubsequenceFN::compress(const StaticContext::Ptr &context)
{
    const Expression::Ptr me(FunctionCall::compress(context));
    if(me != this)
        return me;

    const Expression::Ptr lenArg(m_operands.value(2));
    if(lenArg && lenArg->isEvaluated())
    {
        const xsInteger length = lenArg->as<Literal>()->item().as<Numeric>()->round()->toInteger();

        if(length <= 0)
            return EmptySequence::create(this, context);
    }

    return me;
}

SequenceType::Ptr SubsequenceFN::staticType() const
{
    const SequenceType::Ptr opType(m_operands.first()->staticType());
    const Cardinality opCard(opType->cardinality());

    /* Optimization: we can do much stronger inference here. If the length is a
     * constant, we can constrain the range at least upwards of the
     * cardinality, for instance. */

    /* The subsequence(expr, 1, 1), add empty-sequence() to the static type.
     *
     * Note that we cannot do all these inferences before we've typechecked our
     * operands. The only known case of where our staticType() is called before
     * typeCheck() is through xmlpatternsview, although it wouldn't be
     * surprising if the more exotic paths can achieve that too.
     */
    if(m_hasTypeChecked &&
       m_operands.at(1)->isEvaluated()                                                      &&
       m_operands.count() == 3                                                              &&
       m_operands.at(2)->isEvaluated()                                                      &&
       m_operands.at(1)->as<Literal>()->item().as<Numeric>()->round()->toInteger() == 1     &&
       m_operands.at(2)->as<Literal>()->item().as<Numeric>()->round()->toInteger() == 1)
    {
        return makeGenericSequenceType(opType->itemType(),
                                       opCard.toWithoutMany());
    }
    else
    {
        return makeGenericSequenceType(opType->itemType(),
                                       opCard | Cardinality::zeroOrOne());
    }
}

Expression::Ptr DocFN::typeCheck(const StaticContext::Ptr &context,
                                 const SequenceType::Ptr &reqType)
{
    /* See the doxygen documentation for this function for the explanation
     * to why this implementation is here, as opposed to in
     * qsequencegeneratingfns.cpp. */

    Q_ASSERT(context);

    prepareStaticBaseURI(context);

    const Expression::Ptr uriOp(m_operands.first());

    if(!uriOp->isEvaluated())
        return Expression::Ptr(FunctionCall::typeCheck(context, reqType));

    const Item uriItem(uriOp->evaluateSingleton(context->dynamicContext()));

    if(!uriItem)
        return EmptySequence::create(this, context)->typeCheck(context, reqType); // TODO test this

    /* These two lines were previously in a separate function but are now duplicated
     * in DocFN::evaluateSingleton(), as part of a workaround for solaris-cc-64. */
    const QUrl mayRela(AnyURI::toQUrl<ReportContext::FODC0005>(uriItem.stringValue(), context, this));
    const QUrl uri(context->resolveURI(mayRela, staticBaseURI()));

    /* The URI is supplied statically, so, let's try to be clever. */
    Q_ASSERT_X(context->resourceLoader(), Q_FUNC_INFO,
               "No resource loader is set in the StaticContext.");
    m_type = context->resourceLoader()->announceDocument(uri, ResourceLoader::MayUse);

    if(m_type)
    {
        Q_ASSERT(CommonSequenceTypes::ZeroOrOneDocumentNode->matches(m_type));
        return Expression::Ptr(FunctionCall::typeCheck(context, reqType));
    }
    else
    {
        context->error(QtXmlPatterns::tr("It will not be possible to retrieve %1.").arg(formatURI(uri)),
                       ReportContext::FODC0002, this);
        return Expression::Ptr();
    }
}

QT_END_NAMESPACE
