/* 
 * File:   XreateServer.cpp
 * Author: pgess
 * 
 * Created on March 29, 2016, 11:43 AM
 */

#include "XreateServer.h"
#include "Parser.h"

#include <iostream>
#include <thrift/transport/TSocket.h>
#include <boost/format.hpp>
#include <boost/algorithm/string/join.hpp>

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

class RecordedParserErrors: public Errors{
public:
        RecordedParserErrors(): Errors(), output(L"-- line %d col %d: %ls\n") {}
    
        virtual void SynErr(int line, int col, int n) {
            wchar_t* errorMessage = convertErrorCode(n);
            wstring message ((output % line % col % errorMessage).str());
            log.push_back(string(message.begin(), message.end()));

            coco_string_delete(errorMessage);
            count++;
        }
        
	virtual void Error(int line, int col, const wchar_t *s){
            wstring message ((output % line % col % s).str());
            log.push_back(string(message.begin(),message.end()));
            
            count++;
        }
        
	virtual void Warning(int line, int col, const wchar_t *s){
            wstring message ((output % line % col % s).str());
            log.push_back(string(message.begin(),message.end()));
        }
        
	virtual void Warning(const wchar_t *s){
            wstring message(s);
        
            log.push_back(string(message.begin(),message.end()));
        }
        
        const std::list<std::string> getLog(){
            return log;
        }
        
        
private:
    std::list<std::string> log;
    boost::wformat output;
};

XreateServer::XreateServer() {}

void 
XreateServer::ping(std::string& _return, const std::string& text){
    cout << "ping: "<<text << endl;

    _return = text;
}

void
XreateServer::checkSyntax(SyntaxCheckResult& _return, const std::string& program){
    Scanner scanner(reinterpret_cast<const unsigned char*>(program.c_str()), program.size());
    Parser parser(&scanner);
    delete parser.errors;
    RecordedParserErrors* errors = new RecordedParserErrors();
    parser.errors = errors;
    parser.Parse();
    
    SyntaxCheckResult result;
    result.success = parser.errors->count == 0;
    auto log = errors->getLog();
    result.output = boost::algorithm::join(errors->getLog(), "");
    
    _return = result;
}


XreateServerFactory::~XreateServerFactory() {}
  
AbstractXreateServerIf* 
XreateServerFactory::getHandler(const ::apache::thrift::TConnectionInfo& connInfo)
{
  boost::shared_ptr<TSocket> sock = boost::dynamic_pointer_cast<TSocket>(connInfo.transport);
  cout << "Incoming connection\n";
  cout << "\tSocketInfo: "  << sock->getSocketInfo() << "\n";
  cout << "\tPeerHost: "    << sock->getPeerHost() << "\n";
  cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n";
  cout << "\tPeerPort: "    << sock->getPeerPort() << "\n";
  return new XreateServer();
}


void 
XreateServerFactory::releaseHandler(AbstractXreateServerIf* handler) {
  delete handler;
}