#include "testagent.h"
#include "context/VariableGetter.h"
#include "context/VariableDefinition.h"
#include "context/ContextUtils.h"
#include "GlobalVars.h"
#include "datatable/FieldFormat.h"
#include <iostream>
#include <fstream>

TestAgent::TestAgent(QObject *parent) : QObject(parent)
{

}

TestAgent::~TestAgent()
{
    shutdown();
}

void TestAgent::runAgent()
{
    rls.reset(new RemoteServer(AgString("127.0.0.1"), Agent::DEFAULT_PORT, AgString("admin"), AgString("admin"), false));
    agent.reset(new Agent(rls, "TestAgent", true));
    try
    {
        agent->connect();
    }
    catch(...)
    {
        LOG_AG_INFO("error");
    }
    LOG_AG_INFO("connect");
    initializeAgentContext();
    while(true)
    {
        agent->run();
    }
}


void TestAgent::initializeAgentContext()
{
    FieldFormat *ffTime = FieldFormat::create("datablock", AGG_GLOBAL.DATA_FIELD);
    ffTime->setReadonly(true);

    TableFormatPtr tfTime = TableFormatPtr(new TableFormat(1, 1));
    tfTime->addField(ffTime);

    VariableDefinitionPtr def = VariableDefinitionPtr(new VariableDefinition("test",TableFormatPtr(tfTime),true,true));
    def->setGroup( ContextUtils::GROUP_REMOTE());
    def->setGetter(VariableGetterPtr(new TestVariableGetter()));
    agent->getContext()->addVariableDefinition(def);
}

void TestAgent::shutdown()
{
    agent->disconnect();
}

DataTablePtr TestVariableGetter::get(Context *con, VariableDefinitionPtr def, CallerControllerPtr caller, RequestControllerPtr request)
{
    FieldFormat *ffTime = FieldFormat::create("datablock", AGG_GLOBAL.DATA_FIELD);
    ffTime->setReadonly(true);

    TableFormatPtr tfTime = TableFormatPtr(new TableFormat(1, 1));
    tfTime->addField(ffTime);

    DataTablePtr dt = DataTablePtr(new DataTable(tfTime));
    std::vector<unsigned char> preview = readFile("C:/doc.txt");

    DataPtr ptr = DataPtr(new Data(preview));
    ptr->setName(AgString("fgd"));
    ptr->setPreview(preview);
    dt->addRecord()->setValue(0,ptr);
    return dt;
}

std::vector<BYTE> TestVariableGetter::readFile(const char* filename)
{
    // open the file:
    std::ifstream file(filename, std::ios::binary);

    // Stop eating new lines in binary mode!!!
    file.unsetf(std::ios::skipws);

    // get its size:
    std::streampos fileSize;

    file.seekg(0, std::ios::end);
    fileSize = file.tellg();
    file.seekg(0, std::ios::beg);

    // reserve capacity
    std::vector<BYTE> vec;
    vec.reserve(fileSize);

    // read the data:
    vec.insert(vec.begin(),
               std::istream_iterator<BYTE>(file),
               std::istream_iterator<BYTE>());

    return vec;
}
