/***************************************************************************
 * SPDX-FileCopyrightText: 2024 S. MANKOWSKI stephane@mankowski.fr
 * SPDX-FileCopyrightText: 2024 G. DE BURE support@mankowski.fr
 * SPDX-License-Identifier: GPL-3.0-or-later
 ***************************************************************************/
/** @file
 * This file is a test script.
 *
 * @author Stephane MANKOWSKI / Guillaume DE BURE
 */
#include "skgtestmacro.h"
#include "skgbankincludes.h"

/**
 * The main function of the unit test
 * @param argc the number of arguments
 * @param argv the list of arguments
 */
int main(int argc, char** argv)
{
    Q_UNUSED(argc)
    Q_UNUSED(argv)

    // Init test
    SKGINITTEST(true)

    QDate now = QDate::currentDate();

    {
        // Test objectbase
        SKGDocumentBank document1;
        SKGTESTERROR(QLatin1String("document1.initialize()"), document1.initialize(), true)
        SKGError err;
        {
            SKGTEST(QLatin1String("DOC:getDisplay"), document1.getDisplay(QLatin1String("v_node.unknown")), QLatin1String("v_node.unknown"))
            SKGTEST(QLatin1String("DOC:getDisplay"), document1.getDisplay(QLatin1String("t_comment")), QLatin1String("Comment"))
            SKGTEST(QLatin1String("DOC:getDisplay"), document1.getDisplay(QLatin1String("p_Test")), QLatin1String("Test"))
            SKGTEST(QLatin1String("DOC:getDisplay"), document1.getDisplay(QLatin1String("operation.p_Test")), QLatin1String("operation.Test"))

            SKGServices::SKGAttributesList undoredoAttributes;
            SKGTESTERROR(QLatin1String("OBJBASE:getAttributesDescription)"), document1.getAttributesDescription(QLatin1String("doctransaction"), undoredoAttributes), true)
            SKGTEST(QLatin1String("OBJBASE:undoredoAttributes.count"), undoredoAttributes.count(), 7)
            SKGTEST(QLatin1String("OBJBASE:undoredoAttributes.name"), undoredoAttributes[0].name, QLatin1String("id"))
            SKGTEST(QLatin1String("OBJBASE:undoredoAttributes.type"), static_cast<unsigned int>(undoredoAttributes[0].type), static_cast<unsigned int>(SKGServices::ID))
            SKGTESTBOOL("OBJBASE:undoredoAttributes.notnull", undoredoAttributes[0].notnull, false)
            SKGTEST(QLatin1String("OBJBASE:undoredoAttributes.defaultvalue"), undoredoAttributes[0].defaultvalue, QLatin1String(""))
            SKGTEST(QLatin1String("OBJBASE:undoredoAttributes.name"), undoredoAttributes[2].name, QLatin1String("t_mode"))
            SKGTEST(QLatin1String("OBJBASE:undoredoAttributes.type"), static_cast<unsigned int>(undoredoAttributes[2].type), static_cast<unsigned int>(SKGServices::TEXT))
            SKGTESTBOOL("OBJBASE:undoredoAttributes.notnull", undoredoAttributes[2].notnull, true)
            SKGTEST(QLatin1String("OBJBASE:undoredoAttributes.defaultvalue"), undoredoAttributes[2].defaultvalue, QLatin1String("'U'"))
            /*
            | cid | name         | t_type       | notnull | dflt_value | pk |
            | 0   | id           | INTEGER    | 99      |            | 1  |
            | 1   | name         | TEXT       | 99      |            | 0  |
            | 2   | t_mode         | VARCHAR(1) | 0       | 'U'        | 0  |
            | 3   | d_date | DATE       | 99      |            | 0  |
            | 4   | t_savestep     | VARCHAR(1) | 0       | 'N'        | 0  |
            | 5   | parent       | INTEGER    | 0       |            | 0  |
            */

            QStringList undoredoAttributeNames;
            SKGTESTERROR(QLatin1String("OBJBASE:getAttributesList)"), document1.getAttributesList(QLatin1String("doctransaction"), undoredoAttributeNames), true)
            SKGTEST(QLatin1String("OBJBASE:undoredoAttributeNames.count"), undoredoAttributeNames.count(), 7)
            SKGTEST(QLatin1String("OBJBASE:undoredoAttributeNames"), undoredoAttributeNames[0], QLatin1String("id"))
            SKGTEST(QLatin1String("OBJBASE:undoredoAttributeNames"), undoredoAttributeNames[1], QLatin1String("t_name"))
            SKGTEST(QLatin1String("OBJBASE:undoredoAttributeNames"), undoredoAttributeNames[2], QLatin1String("t_mode"))
            SKGTEST(QLatin1String("OBJBASE:undoredoAttributeNames"), undoredoAttributeNames[3], QLatin1String("d_date"))
            SKGTEST(QLatin1String("OBJBASE:undoredoAttributeNames"), undoredoAttributeNames[4], QLatin1String("t_savestep"))
            SKGTEST(QLatin1String("OBJBASE:undoredoAttributeNames"), undoredoAttributeNames[5], QLatin1String("t_refreshviews"))
            SKGTEST(QLatin1String("OBJBASE:undoredoAttributeNames"), undoredoAttributeNames[6], QLatin1String("i_parent"))

            SKGBEGINTRANSACTION(document1, QLatin1String("OBJBASE 1"), err)
            SKGObjectBase obj1(&document1, QLatin1String("bank"));
            SKGTESTERROR(QLatin1String("OBJBASE:setAttribute"), obj1.setAttribute(QLatin1String("t_name"), QLatin1String("CL")), true)
            SKGTESTERROR(QLatin1String("OBJBASE:save"), obj1.save(), true)

            SKGObjectBase obj2(&document1, QLatin1String("bank"), obj1.getID());
            SKGTESTERROR(QLatin1String("OBJBASE:load"), obj2.load(), true)
            SKGTEST(QLatin1String("OBJBASE:getAttribute"), obj2.getAttribute(QLatin1String("t_name")), QLatin1String("CL"))
            SKGTESTERROR(QLatin1String("OBJBASE:setAttribute"), obj2.setAttribute(QLatin1String("t_name"), QLatin1String("CC")), true)
            SKGTESTERROR(QLatin1String("OBJBASE:save"), obj2.save(), true)

            SKGObjectBase obj3(&document1, QLatin1String("v_bank"), obj2.getID());
            SKGTESTERROR(QLatin1String("OBJBASE:load"), obj3.load(), true)
            SKGTEST(QLatin1String("OBJBASE:getAttribute"), obj3.getAttribute(QLatin1String("t_name")), QLatin1String("CC"))
            SKGTEST(QLatin1String("OBJBASE:getTable"), obj3.getTable(), QLatin1String("v_bank"))
            SKGTESTERROR(QLatin1String("OBJBASE:save"), obj3.save(), true)

            SKGObjectBase obj4(&document1);
            SKGTESTBOOL("OBJBASE:Operator =", (obj2 == obj1), true)
            SKGTESTBOOL("OBJBASE:Operator =", (obj3 == obj1), true)
            SKGTESTBOOL("OBJBASE:Operator =", (obj4 == obj1), false)

            SKGTESTBOOL("OBJBASE:Operator !=", (obj2 != obj1), false)
            SKGTESTBOOL("OBJBASE:Operator !=", (obj3 != obj1), false)
            SKGTESTBOOL("OBJBASE:Operator !=", (obj4 != obj1), true)

            SKGQStringQStringMap att = obj3.getAttributes();
            int nb = obj3.getNbAttributes();
            SKGTEST(QLatin1String("OBJBASE:getNbAttributes"), obj3.getNbAttributes(), att.count())
            for (int i = 0; i < nb; ++i) {
                SKGTRACE << i << ":" << obj3.getAttribute(SKGServices::intToString(i)) << Qt::endl;
            }
            SKGTEST(QLatin1String("OBJBASE:getAttribute"), obj3.getAttribute(QLatin1String("2")), QLatin1String("CC"))
            SKGTESTBOOL("OBJBASE:exist", obj3.exist(), true)
            SKGTESTERROR(QLatin1String("OBJBASE:dump"), obj3.dump(), true)

            SKGTEST(QLatin1String("OBJBASE:getID"), obj3.getID(), 1)
            SKGTESTERROR(QLatin1String("OBJBASE:resetID"), obj3.resetID(), true)
            SKGTEST(QLatin1String("OBJBASE:getID"), obj3.getID(), 0)

            SKGNamedObject tmp1(obj3);
            const SKGNamedObject& tmp2 = tmp1;
            SKGTEST(QLatin1String("OBJBASE:getAttribute"), tmp2.getAttribute(QLatin1String("t_name")), QLatin1String("CC"))

            // Test error
            SKGObjectBase notFound;
            SKGTESTERROR(QLatin1String("OBJBASE:getObject"), document1.getObject(QLatin1String("v_bank"), QLatin1String("t_name='NOTFOUND'"), notFound), false)
            SKGTESTERROR(QLatin1String("OBJBASE:getObject"), document1.getObject(QLatin1String("parameters"), QLatin1String("'"), notFound), false)
            SKGTESTERROR(QLatin1String("OBJBASE:getObject"), document1.getObject(QLatin1String("v_bank"), 9999, notFound), false)
        }
    }
    // ============================================================================
    // ============================================================================
    {
        // Test bank document
        SKGDocumentBank document1;
        SKGTESTERROR(QLatin1String("document1.initialize()"), document1.initialize(), true)
        SKGError err;
        SKGTEST(QLatin1String("BANK:getNbTransaction"), document1.getNbTransaction(), 0) {
            // Scope of the transaction
            SKGBEGINTRANSACTION(document1, QLatin1String("BANK_T1"), err)

            // The code here
            IFOK(err) {
                SKGTEST(QLatin1String("BANK:getDepthTransaction"), document1.getDepthTransaction(), 1)

                // Example; transaction succeeded
                SKGTESTERROR(QLatin1String("BANK:setParameter"), document1.setParameter(QLatin1String("ATT1"), QLatin1String("VAL1")), true)
                SKGTESTERROR(QLatin1String("BANK:setParameter"), document1.setParameter(QLatin1String("ATT2"), QLatin1String("VAL2")), true)
                SKGTESTERROR(QLatin1String("BANK:setParameter"), document1.setParameter(QLatin1String("ATT3"), QLatin1String("VAL2")), true)

                QStringList oResult;
                SKGTESTERROR(QLatin1String("BANK:getDistinctValues"), document1.getDistinctValues(QLatin1String("parameters"), QLatin1String("t_value"), QLatin1String("t_value like 'VAL%'"), oResult), true)
                SKGTEST(QLatin1String("BANK:oResult.size"), oResult.size(), 2)

                // Test account
                SKGTESTERROR(QLatin1String("BANK:addOrModifyAccount"), document1.addOrModifyAccount(QLatin1String("Courant"), QLatin1String("123"), QLatin1String("LCL")), true)
                SKGTESTERROR(QLatin1String("BANK:addOrModifyAccount"), document1.addOrModifyAccount(QLatin1String("Livret A"), QLatin1String("456"), QLatin1String("CREDIT COOP")), true)
                SKGTESTERROR(QLatin1String("BANK:addOrModifyAccount"), document1.addOrModifyAccount(QLatin1String("Codevi"), QLatin1String("789"), QLatin1String("NEF")), true)
                SKGTESTERROR(QLatin1String("BANK:addOrModifyAccount"), document1.addOrModifyAccount(QLatin1String("PEA"), QLatin1String("ABC"), QLatin1String("CA")), true)
                SKGTESTERROR(QLatin1String("BANK:getDistinctValues"), document1.getDistinctValues(QLatin1String("account"), QLatin1String("t_name"), oResult), true)
                SKGTEST(QLatin1String("BANK:oResult.size"), oResult.size(), 4)

                // Test units
                SKGTESTERROR(QLatin1String("BANK:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QLatin1String("E"), now, 1), true)
                SKGTESTERROR(QLatin1String("BANK:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QLatin1String("$"), now, 1.6), true)  // Oups, it is an error
                SKGTESTERROR(QLatin1String("BANK:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QLatin1String("$"), now, 0.625), true)  // it is better now
                SKGTESTERROR(QLatin1String("BANK:getDistinctValues"), document1.getDistinctValues(QLatin1String("unitvalue"), QLatin1String("rd_unit_id"), oResult), true)
                SKGTEST(QLatin1String("BANK:oResult.size"), oResult.size(), 2)
            }
        }  // A commit is done here because the scope is close

        QStringList oResult;
        SKGTESTERROR(QLatin1String("BANK:getDistinctValues"), document1.getDistinctValues(QLatin1String("unit"), QLatin1String("t_name"), oResult), true)
        SKGTEST(QLatin1String("BANK:oResult.size"), oResult.size(), 2)
        SKGTESTERROR(QLatin1String("BANK:undoRedoTransaction(BANK_T1, SKGDocument::UNDO)"), document1.undoRedoTransaction(), true)
        SKGTESTERROR(QLatin1String("BANK:getDistinctValues"), document1.getDistinctValues(QLatin1String("unit"), QLatin1String("t_name"), oResult), true)
        SKGTEST(QLatin1String("BANK:oResult.size"), oResult.size(), 0)
        SKGTESTERROR(QLatin1String("BANK:undoRedoTransaction(BANK_T1, SKGDocument::REDO)"), document1.undoRedoTransaction(SKGDocument::REDO), true)
        SKGTESTERROR(QLatin1String("BANK:getDistinctValues"), document1.getDistinctValues(QLatin1String("unit"), QLatin1String("t_name"), oResult), true)
        SKGTEST(QLatin1String("BANK:oResult.size"), oResult.size(), 2)

        SKGTESTERROR(QLatin1String("BANK:err"), err, true)
    }

    // End test
    SKGENDTEST()
}
