/****************************************************************************
**
** Copyright (C) 2017 Ford Motor Company
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtRemoteObjects module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "utils.h"

#include "repparser.h"

#include <moc.h>

#define _(X) QString::fromLatin1(X)

QT_BEGIN_NAMESPACE

static QByteArray join(const QVector<QByteArray> &array, const QByteArray &separator)
{
    QByteArray res;
    const int sz = array.size();
    if (!sz)
        return res;
    for (int i = 0; i < sz - 1; i++)
        res += array.at(i) + separator;
    res += array.at(sz - 1);
    return res;
}

static QVector<QByteArray> generateProperties(const QVector<PropertyDef> &properties, bool isPod=false)
{
    QVector<QByteArray> ret;
    for (const PropertyDef& property : properties) {
        if (!isPod && property.notifyId == -1 && !property.constant) {
            qWarning() << "Skipping property" << property.name << "because is non-notifiable & non-constant";
            continue; // skip non-notifiable properties
        }
        QByteArray prop = property.type + " " + property.name;
        if (property.constant)
            prop += " CONSTANT";
        if (property.write.isEmpty() && !property.read.isEmpty())
            prop += " READONLY";
        ret << prop;
    }
    return ret;
}

static QByteArray generateFunctions(const QByteArray &type, const QVector<FunctionDef> &functionList)
{
    QByteArray ret;
    for (const FunctionDef &func : functionList) {
        if (func.access != FunctionDef::Public)
            continue;

        ret += type + "(" + func.normalizedType + " " + func.name + "(";
        const int sz = func.arguments.size();
        if (sz) {
            for (int i = 0; i < sz - 1 ; i++) {
                const ArgumentDef &arg = func.arguments.at(i);
                ret += arg.normalizedType + " " + arg.name + ", ";
            }

            const ArgumentDef &arg = func.arguments.at(sz -1);
            ret += arg.normalizedType + " " + arg.name;
        }
        ret += "));\n";
    }
    return ret;
}

static bool highToLowSort(int a, int b)
{
    return a > b;
}

static QVector<FunctionDef> cleanedSignalList(const ClassDef &cdef)
{
    auto ret = cdef.signalList;
    QVector<int> positions;
    for (const PropertyDef &prop :  qAsConst(cdef.propertyList)) {
        if (prop.notifyId != -1) {
            Q_ASSERT(prop.notify == ret.at(prop.notifyId).name);
            positions.push_back(prop.notifyId);
        }
    }
    std::sort(positions.begin(), positions.end(), highToLowSort);
    for (int pos : qAsConst(positions))
        ret.removeAt(pos);
    return ret;
}

static QVector<FunctionDef> cleanedSlotList(const ClassDef &cdef)
{
    auto ret = cdef.slotList;
    for (const PropertyDef &prop : qAsConst(cdef.propertyList)) {
        if (!prop.write.isEmpty()) {
            auto it = ret.begin();
            while (it != ret.end()) {
                const FunctionDef& fdef = *it;
                if (fdef.name == prop.write &&
                    fdef.arguments.size() == 1 &&
                    fdef.arguments[0].type.name == prop.type) {
                    ret.erase(it);
                    break;
                }
                ++it;
            }
        }
    }
    return ret;
}

QByteArray generateClass(const ClassDef &cdef, bool alwaysGenerateClass /* = false */)
{
    const auto signalList = cleanedSignalList(cdef);
    if (signalList.isEmpty() && cdef.slotList.isEmpty() && !alwaysGenerateClass)
        return "POD " + cdef.classname + "(" + join(generateProperties(cdef.propertyList, true), ", ") + ")\n";

    QByteArray ret("class " + cdef.classname + "\n{\n");
    if (!cdef.propertyList.isEmpty())
        ret += "    PROP(" + join(generateProperties(cdef.propertyList), ");\n    PROP(") + ");\n";
    ret += generateFunctions("    SLOT", cleanedSlotList(cdef));
    ret += generateFunctions("    SIGNAL", signalList);
    ret += "}\n";
    return ret;
}

static QVector<PODAttribute> propertyList2PODAttributes(const QVector<PropertyDef> &list)
{
    QVector<PODAttribute> ret;
    for (const PropertyDef &prop : list)
        ret.push_back(PODAttribute(_(prop.type), _(prop.name)));
    return ret;
}

QVector<ASTProperty> propertyList2AstProperties(const QVector<PropertyDef> &list)
{
    QVector<ASTProperty> ret;
    for (const PropertyDef &property : list) {
        if (property.notifyId == -1 && !property.constant) {
            qWarning() << "Skipping property" << property.name << "because is non-notifiable & non-constant";
            continue; // skip non-notifiable properties
        }
        ASTProperty prop;
        prop.name = _(property.name);
        prop.type = _(property.type);
        prop.modifier = property.constant
                        ? ASTProperty::Constant
                        : property.write.isEmpty() && !property.read.isEmpty()
                          ? ASTProperty::ReadOnly
                          : ASTProperty::ReadWrite;
        ret.push_back(prop);
    }
    return ret;
}

QVector<ASTFunction> functionList2AstFunctionList(const QVector<FunctionDef> &list)
{
    QVector<ASTFunction> ret;
    for (const FunctionDef &fdef : list) {
        if (fdef.access != FunctionDef::Public)
            continue;

        ASTFunction func;
        func.name = _(fdef.name);
        func.returnType = _(fdef.type.name);
        for (const ArgumentDef &arg : fdef.arguments)
            func.params.push_back(ASTDeclaration(_(arg.type.name), _(arg.name)));
        ret.push_back(func);
    }
    return ret;
}

AST classList2AST(const QVector<ClassDef> &classList)
{
    AST ret;
    for (const ClassDef &cdef : classList) {
        const auto signalList = cleanedSignalList(cdef);
        if (signalList.isEmpty() && cdef.slotList.isEmpty()) {
            POD pod;
            pod.name = _(cdef.classname);
            pod.attributes = propertyList2PODAttributes(cdef.propertyList);
            ret.pods.push_back(pod);
        } else {
            ASTClass cl(_(cdef.classname));
            cl.properties = propertyList2AstProperties(cdef.propertyList);
            cl.signalsList = functionList2AstFunctionList(signalList);
            cl.slotsList = functionList2AstFunctionList(cleanedSlotList(cdef));
            ret.classes.push_back(cl);
        }
    }
    return ret;
}

QT_END_NAMESPACE
