#include <stdio.h>
#include "spir.hpp"
#include "spir_ffi.h"

void SPIR::init(uint32_t num_threads)
{
    spir_init(num_threads);
}

SPIR_Client::SPIR_Client(uint8_t r, string &pub_params)
{
    ClientNewRet ret = spir_client_new(r);
    pub_params.assign(ret.pub_params.data, ret.pub_params.len);
    spir_vecdata_free(ret.pub_params);
    this->client = ret.client;
}

SPIR_Client::~SPIR_Client()
{
    spir_client_free(this->client);
}

string SPIR_Client::preproc(uint32_t num_preproc)
{
    VecData msg = spir_client_preproc(this->client, num_preproc);
    string ret(msg.data, msg.len);
    spir_vecdata_free(msg);
    return ret;
}

void SPIR_Client::preproc_finish(const string &server_preproc)
{
    spir_client_preproc_finish(this->client, server_preproc.data(),
        server_preproc.length());
}

string SPIR_Client::query(size_t idx)
{
    VecData msg = spir_client_query(this->client, idx);
    string ret(msg.data, msg.len);
    spir_vecdata_free(msg);
    return ret;
}

SPIR::DBEntry SPIR_Client::query_finish(const string &server_resp)
{
    return spir_client_query_finish(this->client,
        server_resp.data(), server_resp.length());
}

SPIR_Server::SPIR_Server(uint8_t r, const string &pub_params)
{
    this->server = spir_server_new(r, pub_params.data(),
        pub_params.length());
}

SPIR_Server::~SPIR_Server()
{
    spir_server_free(this->server);
}

string SPIR_Server::preproc_process(const string &msg)
{
    VecData retmsg = spir_server_preproc_process(this->server, msg.data(),
        msg.length());
    string ret(retmsg.data, retmsg.len);
    spir_vecdata_free(retmsg);
    return ret;
}

string SPIR_Server::query_process(const string &client_query,
        const SPIR::DBEntry *db, size_t rot, SPIR::DBEntry blind)
{
    VecData retmsg = spir_server_query_process(this->server,
        client_query.data(), client_query.length(), db, rot, blind);
    string ret(retmsg.data, retmsg.len);
    spir_vecdata_free(retmsg);
    return ret;
}
