#include "remarkupparser.h"
#include "PhabricatorParserPrivate.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include <QThread>
#include <QDebug>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <QMetaType>
#include <stdio.h>
#include <QFile>

using namespace std;
using namespace std;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;

const char* SOCKET_NAME  = tempnam(0,0);
const string SERVER_INDEX  = "/private/prg/code/xreate/documentation-tools/RemarkupParser/php/index.php";
const string LOCK_FILENAME  = "/var/lock/phabricator-parser";

void
RemarkupParser::startPhabricatorParserServer(){
    //acquire lock:
//    if (-1 == open( LOCK_FILENAME.c_str(), O_RDWR | O_CREAT | O_EXCL, 0666 )){
//        qDebug()<<"Lock acquiring failure";
//        return;
//    }

    phpServerId = fork();
    if(phpServerId < 0 )
    {
       qDebug()<<"fork failure";
       return;
    }

    //child
    if(phpServerId == 0)
    {
        execl("/usr/bin/php", "php", SERVER_INDEX.c_str(), SOCKET_NAME, NULL);
        _exit(0);
    }

    qDebug()<<"successfully forked";
}

RemarkupParser::RemarkupParser(){
    startPhabricatorParserServer();
}

bool
RemarkupParser::connect(){
    qDebug()<<"RemarkupParser::connect";
    if (!QFile::exists(QString::fromLatin1(SOCKET_NAME))) return false;

    boost::shared_ptr<TTransport> socket(new TSocket(SOCKET_NAME));
    boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
    boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));

    client = new PhabricatorParserPrivateClient (protocol);
    transport->open();

    return true;
}

Blocks
RemarkupParser::parse(const QString& text)
{
    qDebug()<<"RemarkupParser:: parsing";
    std::vector<Block>  output;

    if (!client){
        qDebug() << "Parser does not connected";
        return output;
    }

    try {
        client->parse(output, text.toStdString());
    } catch (TException& tx) {
        qDebug() << "RemarkupParser exception: " << tx.what();
    }

    return output;
}

RemarkupParser::~RemarkupParser(){
    delete client;
  //  remove(LOCK_FILENAME.c_str());

    qDebug()<<"RemarkupParser::kill PHP";
    kill(phpServerId, SIGKILL);
    remove(SOCKET_NAME);
}
