#include "dslib.h"
#include "datastreamer.hpp"
#include <sstream>
#include <cstring>

using namespace std;

unsigned char* _errmsg = NULL;

void datastreamer_clearexception()
{
    delete [] _errmsg;
    _errmsg = NULL;
}

void datastreamer_collectotlexception(otl_exception& e)
{
    ostringstream msg;

    msg << "*** Exception: " << e.msg << endl
        << "Statement:" << endl << e.stm_text << endl
        << "Responsible Variable: " << e.var_info << endl;

    datastreamer_clearexception();

    _errmsg = new unsigned char[msg.str().length() + 1];
    strncpy((char*)_errmsg, msg.str().c_str(), msg.str().length());
}

datastreamer_t DLL_EXPORT datastreamer_create()
{
    return new DataStreamer;
}

void DLL_EXPORT datastreamer_destroy(datastreamer_t dt)
{
    DataStreamer *mydt = (DataStreamer*)dt;
    delete mydt;
}

const unsigned char* DLL_EXPORT datastreamer_errormessage()
{
    return _errmsg;
}

int DLL_EXPORT datastreamer_open(datastreamer_t dt, unsigned char* dsn, unsigned char* uid, unsigned char* pwd)
{
    try {
        datastreamer_clearexception();
        DataStreamer *mydt = (DataStreamer*)dt;
        mydt->Open(dsn, uid, pwd);
        return 0;
    }
    catch(otl_exception& e) {
        datastreamer_collectotlexception(e);
        return 1;
    }
}

int DLL_EXPORT datastreamer_setfield(datastreamer_t dt, unsigned char* t, unsigned char* p, unsigned char* d)
{
    try {
        datastreamer_clearexception();
        DataStreamer *mydt = (DataStreamer*)dt;
        mydt->SetField(t, p, d);
        return 0;
    }
    catch(otl_exception& e) {
        datastreamer_collectotlexception(e);
        return 1;
    }
}

int DLL_EXPORT datastreamer_setvalue(datastreamer_t dt, int id, char* val)
{
    try {
        datastreamer_clearexception();
        DataStreamer *mydt = (DataStreamer*)dt;
        mydt->SetValue(id, val);
        return 0;
    }
    catch(otl_exception& e) {
        datastreamer_collectotlexception(e);
        return 1;
    }
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            // attach to process
            // return FALSE to fail DLL load
            break;

        case DLL_PROCESS_DETACH:
            // detach from process
            break;

        case DLL_THREAD_ATTACH:
            // attach to thread
            break;

        case DLL_THREAD_DETACH:
            // detach from thread
            break;
    }
    return TRUE; // succesful
}

