#include <QtCore/QCoreApplication>
#include <QDebug>
#include <QUrl>
#include <QTime>

#include "field.h"
#include "query.h"
#include "database.h"
#include "table.h"
#include "set.h"
#include "reference.h"
#include "timestamp.h"
#include "id.h"
#include "foreignkeyvalue.h"
#include "join.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Database db( QUrl( "sqlite:///tmp/test.db" ) );
    if( !db.open() )
        qDebug() << db.lastError();

    Field arg1(db.db(), "bar1", QVariant::String );

    Field arg2(db.db(), "bar2", QVariant::Int );
    arg2.setUnique(true);

    Field arg3(db.db(), "bar3", QVariant::Int );
    arg3.setCheck( arg3 != 12  );
    arg3.setNotNull(true);

    Field arg4(db.db(), "bar4", QVariant::Time );

    Timestamp arg5(db.db(), "bar5");
    arg5.setNotNull(true);

    QMap<QString,QVariant> props;
    Table table1 = db.defineTable( "foo", QList<Field>() << arg1 << arg2 << arg3 << arg4, props );
    Reference arg6( "bar6", table1 );
    Table table2 = db.defineTable( "bar", QList<Field>() << arg6 << arg5, props);

    Query query = ((table1["bar1"] == "Blah") &&
                   ( table1["bar2"] == 10)) ||
                   ( table1["bar3"].sum() > 5) ||
                   ( table1["bar4"] == table2.id());

    {
        Field arg7 = arg6;
        arg6.setProperty("test", "test");
        qDebug() << arg7.property("test");
        arg7.setProperty("test", "bar");
    }
    qDebug() << table2["bar6"].property("test");

    QMap<QString,QVariant> values1;
    values1["bar1"] = "Test";
    values1["bar2"] = 5;
    values1["bar3"] = 6;
    qDebug() << "Insert1:" << table1.insert( values1 );

    QMap<QString,QVariant> values2;
    values2["bar1"] = "Test";
    values2["bar2"] = 6;
    values2["bar3"] = 6;
    qDebug() << "Insert2:" << table1.insert( values2 );



    Set result = db.select( QList<Field>()
                            << table1["bar1"]
                            << table1["bar2"]
                            << table1["bar4"],
                            table1["bar1"] == "Test" );
    qDebug() << "Select error:" << result.lastError();

    qDebug() << "Result:" << result.values().values();

    result.setValue(table1["bar2"], 11);
    result.setValue(table1["bar4"], QTime::currentTime() );

    qDebug() << "Commit1:" << result.commitCurrentRow();
    result.select();
    qDebug() << "Select error:" << result.lastError();

    result.setValue(table1["bar1"],"Foobar");
    qDebug() << "Commit2:" << result.commitCurrentRow();

    result = db.select( QList<Field>()
                            << table1["bar1"],
                            table1["bar3"] == 6 );
    qDebug() << "Select error:" << result.lastError();
    result.setValue(table1["bar1"], "Blah");
    result.nextRow();
    result.setValue(table1["bar1"], "Blarg");
    qDebug() << "Commit3:" << result.commitSet();


    QMap<QString,QVariant> positionProperties;
    Field position( db.db(), "name", QVariant::String );
    Table positions = db.defineTable( "positions", QList<Field>() << position, positionProperties );


    QMap<QString,QVariant> employeeProperties;
    Field name(db.db(), "name", QVariant::String );
    Field office(db.db(), "office", QVariant::String );
    Reference employeePosition( "position", position );
    Table employees = db.defineTable( "employees", QList<Field>() << name << office << employeePosition, employeeProperties );

    QMap<QString,QVariant> positionData;
    positionData[position.name()] = "President";
    positions.insert(positionData);

    positionData[position.name()] = "Vice President";
    positions.insert(positionData);

    positionData[position.name()] = "Sales";
    positions.insert(positionData);

    positionData[position.name()] = "Engineering";
    positions.insert(positionData);

    QMap<QString,QVariant> employeeData;
    employeeData[name.name()] = "Mr President";
    employeeData[office.name()] = "L301";
    employeeData[employeePosition.name()] = ForeignKeyValue(employeePosition, position == "President");
    employees.insert(employeeData);

    employeeData[name.name()] = "Mr VP";
    employeeData[office.name()] = "L302";
    employeeData[employeePosition.name()] = ForeignKeyValue(employeePosition, "Vice President");;
    employees.insert(employeeData);

    employeeData[name.name()] = "Slick";
    employeeData[office.name()] = "L100";
    employeeData[employeePosition.name()] = ForeignKeyValue(employeePosition, position == "Sales");;
    employees.insert(employeeData);

    employeeData[name.name()] = "Geek";
    employeeData[office.name()] = "B100";
    employeeData[employeePosition.name()] = ForeignKeyValue(employeePosition, "Engineering");;
    employees.insert(employeeData);

    Set roster = db.select( QList<Field>()
                            << employees[name.name()]
                            << positions[position.name()]
                            << employees[office.name()],
                            Join(employees[employeePosition.name()], positions.id() ));

    roster = db.select( QList<Field>()
                            << employees[name.name()]
                            << positions[position.name()]
                            << employees[office.name()],
                            Join(employees[employeePosition.name()], positions ));

    roster = db.select( QList<Field>()
                            << employees[name.name()]
                            << positions[position.name()]
                            << employees[office.name()],
                            Join(employeePosition));

    Set promotion = db.select( QList<Field>()
                            << employees[name.name()]
                            << positions[position.name()]
                            << employees[office.name()],
                            Join(employeePosition) && employees[name.name()] == "Geek" );
    promotion.setValue( positions[position.name()], "Sales" );
    promotion.commitSet();

}

