/***************************************************************************
 *   Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>  *
 ***************************************************************************/
/** @file
 * This file is a test script.
 *
 * @author Stephane MANKOWSKI / Guillaume DE BURE
 */
#include <qfile.h>

#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgtraces.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();

    // ============================================================================
    // Init
    QString filename = SKGTest::getTestPath("OUT") % "/skgtestbigdocument/skgtestbigdocument.skg";

    {
        // Test bank document
        SKGDocumentBank document1;
        SKGTESTERROR("document1.initialize()", document1.initialize(), true);
        SKGUnitValueObject unit_euro_val1;
        SKGBankObject bank(&document1);
        SKGAccountObject account;
        SKGError err;
        {
            // Scope of the transaction
            SKGBEGINTRANSACTION(document1, "BANK_T1", err);

            // Creation bank
            SKGTESTERROR("BANK:setName", bank.setName("CREDIT COOP"), true);
            SKGTESTERROR("BANK:save", bank.save(), true);

            // Creation account
            SKGTESTERROR("BANK:addAccount", bank.addAccount(account), true);
            SKGTESTERROR("ACCOUNT:setName", account.setName("Courant steph"), true);
            SKGTESTERROR("ACCOUNT:setNumber", account.setNumber("12345P"), true);
            SKGTESTERROR("ACCOUNT:save", account.save(), true);

            // Creation unit
            SKGUnitObject unit_euro(&document1);
            SKGTESTERROR("UNIT:setName", unit_euro.setName("euro"), true);
            SKGTESTERROR("UNIT:save", unit_euro.save(), true);

            // Creation unitvalue
            SKGTESTERROR("UNIT:addUnitValue", unit_euro.addUnitValue(unit_euro_val1), true);
            SKGTESTERROR("UNITVALUE:setQuantity", unit_euro_val1.setQuantity(1), true);
            SKGTESTERROR("UNITVALUE:setDate", unit_euro_val1.setDate(now), true);
            SKGTESTERROR("UNITVALUE:save", unit_euro_val1.save(), true);

            // Creation categories
            SKGCategoryObject* cats = new SKGCategoryObject[30];
            for (int i = 0; i < 10; ++i) {
                cats[i] = SKGCategoryObject(&document1);
                SKGTESTERROR("CAT:setName", cats[i].setName("cat_" % SKGServices::intToString(i)), true);
                SKGTESTERROR("CAT:save", cats[i].save(), true);

                for (int j = 0; j < 2; ++j) {
                    int indexSubCat = 10 * (j + 1) + i;
                    SKGTESTERROR("CAT:addCategory", cats[i].addCategory(cats[indexSubCat]), true);
                    SKGTESTERROR("CAT:setName", cats[indexSubCat].setName("cat_" % SKGServices::intToString(i) % '_' % SKGServices::intToString(j)), true);
                    SKGTESTERROR("CAT:save", cats[indexSubCat].save(), true);
                }
            }

            // Creation payees
            SKGPayeeObject* payees = new SKGPayeeObject[10];
            for (int i = 0; i < 10; ++i) {
                payees[i] = SKGPayeeObject(&document1);
                SKGTESTERROR("PAY:setName", payees[i].setName("pay_" % SKGServices::intToString(i)), true);
                SKGTESTERROR("PAY:save", payees[i].save(), true);
            }

            // Mode
            QString* modes = new QString[5];
            modes[0] = "cheque";
            modes[1] = "carte";
            modes[2] = "tip";
            modes[3] = "virement";
            modes[4] = "espece";

            // Comments
            QString* comments = new QString[3];
            comments[0] = "bla bla";
            comments[1] = "hello world";
            comments[2] = "youpi";

            // Creation operation
            SKGOperationObject mainOperation;
            for (int i = 1; i <= 365 * 10; ++i) {
                SKGOperationObject op_1;
                SKGTESTERROR("ACCOUNT:addOperation", account.addOperation(op_1), true);
                SKGTESTERROR("OPE:setNumber", op_1.setNumber(1000 + i), true);
                SKGTESTERROR("OPE:setMode", op_1.setMode(modes[i % 5]), true);
                SKGTESTERROR("OPE:setComment", op_1.setComment(comments[i % 3]), true);
                SKGTESTERROR("OPE:setDate", op_1.setDate(now.addDays(-i)), true);
                SKGTESTERROR("OPE:setUnit", op_1.setUnit(unit_euro), true);
                SKGTESTERROR("OPE:setStatus", op_1.setStatus((i < 20 ? SKGOperationObject::NONE : (i < 40 ? SKGOperationObject::POINTED : SKGOperationObject::CHECKED))), true);
                SKGTESTERROR("OPE:bookmark", op_1.bookmark(i % 2 == 0), true);
                SKGTESTERROR("OPE:save", op_1.save(), true);
                if (i == 1) {
                    mainOperation = op_1;
                    mainOperation.setGroupOperation(mainOperation);
                    SKGTESTERROR("OPE:save", mainOperation.save(), true);
                } else {
                    if (!op_1.isBookmarked()) {
                        op_1.setGroupOperation(mainOperation);
                    }
                    SKGTESTERROR("OPE:save", op_1.save(), true);
                }

                // Creation suboperation
                for (int j = 1; j <= 2; ++j) {
                    SKGSubOperationObject subop_1;
                    SKGTESTERROR("OPE:addSubOperation", op_1.addSubOperation(subop_1), true);
                    SKGTESTERROR("SUBOPE:setCategory", subop_1.setCategory(cats[i % 30]), true);
                    SKGTESTERROR("SUBOPE:setQuantity", subop_1.setQuantity(((i * j) % 60) - 10), true);
                    SKGTESTERROR("SUBOPE:setOrder", subop_1.setOrder(i), true);
                    SKGTEST("SUBOPE:getOrder", subop_1.getOrder(), i);
                    SKGTESTERROR("SUBOPE:save", subop_1.save(), true);
                }
            }

            cats[0].merge(cats[1]);
            payees[0].merge(payees[1]);

            // Delete
            delete [] cats;
            delete [] modes;
            delete [] comments;
            delete [] payees;
        }  // A commit is done here because the scope is close

        SKGTESTERROR("ACCOUNT:getCurrentAmount", account.load(), true);
        SKGTEST("ACCOUNT:getCurrentAmount", account.getCurrentAmount(), 140165);

        QFile(filename).remove();
        SKGTESTERROR("DOC:saveAs", document1.saveAs(filename), true);
    }

    // ============================================================================
    {
        SKGTraces::SKGPerfo = true;
        SKGTRACEIN(0, "openTest");

        // Test bank document
        SKGDocumentBank document1;
        {
            SKGTRACEIN(0, "openTest-Load");
            SKGTESTERROR("document1.load", document1.load(SKGTest::getTestPath("OUT") % "/skgtestbigdocument/skgtestbigdocument.skg"), true);
        }

        {
            SKGTRACEIN(0, "openTest-Get");
            SKGAccountObject account;
            SKGTESTERROR("SKGAccountObject::getObjectByName", SKGAccountObject::getObjectByName(&document1, "v_account", "Courant steph", account), true);
            SKGTEST("ACCOUNT:getCurrentAmount", account.getCurrentAmount(), 140165);

            SKGAccountObject::SKGListSKGObjectBase objects;
            SKGTESTERROR("SKGAccountObject::getObjects", document1.getObjects("v_operation", "", objects), true);

            int nbobj = 0;
            SKGTESTERROR("SKGAccountObject::getNbObjects", document1.getNbObjects("v_operation", "", nbobj), true);
        }

        {
            SKGTRACEIN(0, "openTest-Save");
            SKGTESTERROR("document1.save", document1.save(), true);
        }
    }

    // End test
    SKGENDTEST();
}
