#include "cbasetypes.h"
#include "sql.h"
#include "mmo.h"
#include <iostream>

int read_config();

const int8* login;
const int8* password;
const int8* host;
uint16 port;
const int8* database;

struct oldkeys_t
{
    uint8 keysList[320];
    uint8 seenList[320];
};

int main()
{
    Sql_t* SqlHandleRead = Sql_Malloc();
    Sql_t* SqlHandleWrite = Sql_Malloc();
    if (read_config())
    {
        return 1;
    }

    if (Sql_Connect(SqlHandleRead, login,
        password,
        host,
        port,
        database) == SQL_ERROR || 
        Sql_Connect(SqlHandleWrite, login,
        password,
        host,
        port,
        database) == SQL_ERROR )
    {
        std::cout << "Could not connect to database";
    }

    const int8* fmtQuery =
        "SELECT "
        "charid,"
        "keyitems "
        "FROM chars";

    auto ret = Sql_Query(SqlHandleRead, fmtQuery);

    while (Sql_NextRow(SqlHandleRead) == SQL_SUCCESS)
    {
        auto charid = Sql_GetUIntData(SqlHandleRead, 0);
        oldkeys_t oldkeys;
        keyitems_t newkeys;
        size_t length = 0;
        int8* keyitems = nullptr;
        Sql_GetData(SqlHandleRead, 1, &keyitems, &length);
        memcpy(oldkeys.keysList, keyitems, (length > sizeof(oldkeys) ? sizeof(oldkeys) : length));

        memcpy(&newkeys.tables[0].keyList, oldkeys.keysList, 512 / 8);
        memcpy(&newkeys.tables[0].seenList, oldkeys.seenList, 512 / 8);
        memcpy(&newkeys.tables[1].keyList, oldkeys.keysList+64, 512 / 8);
        memcpy(&newkeys.tables[1].seenList, oldkeys.seenList+64, 512 / 8);
        memcpy(&newkeys.tables[2].keyList, oldkeys.keysList+(64*2), 512 / 8);
        memcpy(&newkeys.tables[2].seenList, oldkeys.seenList+(64*2), 512 / 8);
        memcpy(&newkeys.tables[3].keyList, oldkeys.keysList+(64*3), 512 / 8);
        memcpy(&newkeys.tables[3].seenList, oldkeys.seenList+(64*3), 512 / 8);
        memcpy(&newkeys.tables[4].keyList, oldkeys.keysList+(64*4), 512 / 8);
        memcpy(&newkeys.tables[4].seenList, oldkeys.seenList+(64*4), 512 / 8);

        const int8* fmtQuery = "UPDATE chars SET keyitems = '%s' WHERE charid = %u;";

        int8 keyitems_safe[sizeof(newkeys) * 2 + 1];
        Sql_EscapeStringLen(SqlHandleWrite, keyitems_safe, (const int8*)&newkeys, sizeof(newkeys));

        Sql_Query(SqlHandleWrite, fmtQuery, keyitems_safe, charid);
    }
}

int read_config()
{
    int8 line[1024], w1[1024], w2[1024];
    FILE* fp;

    fopen_s(&fp, "./conf/map_darkstar.conf", "r");

    if (fp == nullptr)
    {
        std::cout << "Map configuration file not found at config.txt" << std::endl;
        return 1;
    }

    while (fgets(line, sizeof(line), fp))
    {
        int8* ptr;

        if (line[0] == '#')
        {
            continue;
        }
        if (sscanf(line, "%[^:]: %[^\t\r\n]", w1, w2) < 2)
        {
            continue;
        }

        //Strip trailing spaces
        ptr = w2 + strlen(w2);
        while (--ptr >= w2 && *ptr == ' ');
        ptr++;
        *ptr = '\0';

        if (strcmp(w1, "mysql_host") == 0)
        {
            host = aStrdup(w2);
        }
        else if (strcmp(w1, "mysql_login") == 0)
        {
            login = aStrdup(w2);
        }
        else if (strcmp(w1, "mysql_password") == 0)
        {
            password = aStrdup(w2);
        }
        else if (strcmp(w1, "mysql_port") == 0)
        {
            port = atoi(w2);
        }
        else if (strcmp(w1, "mysql_database") == 0)
        {
            database = aStrdup(w2);
        }
    }

    fclose(fp);
    return 0;
}