/*!
  @file
  QxtXmlRpc, a Qt4 library for XML-RPC network communication

  (C) 2006 Music Pictures, Ltd. (www.musicpictures.com)
  @author Tobias G. Pfeiffer (tgpfeiffer@web.de)
  @date 2007/02/05
  @version 0.3

  See http://qtnode.net/wiki/QxtXmlRpc or the README file for license terms.
*/

#include <QtCore>

#include "qxtxmlrpcclient.h"
#include "qxtxmlrpcrequestcomposer.h"
#include "qxtxmlrpcresponseparser.h"
 #include <stdio.h>
 #include <iostream>
 using namespace std;

QxtXmlRpcClient::QxtXmlRpcClient(QUrl serverUrl) : url(serverUrl) {
    http = new QHttp();
	//url.setPort(80);
// 	QTextStream cout(stdout, QIODevice::WriteOnly);
// 	cout<<"url.host(): "<<url.host()<<endl;
// 	cout<<"url.port(): "<<url.port()<<endl;
    http->setHost(url.host(), url.port());
    connect(http, SIGNAL(requestFinished(int, bool)), this, SLOT(handleResponse(int, bool)));
}

QxtXmlRpcClient::~QxtXmlRpcClient() {
    delete http;
}

int QxtXmlRpcClient::call(QString procName, QList<QVariant> params) {
    QxtXmlRpcRequestComposer composer(procName);
    QVariant var;
    foreach(var, params) {
        composer.appendArgument( var );
    }
    QByteArray xml = composer.getXmlRequest().toUtf8();
// 	cout<<"start xml"<<endl;
// 	QTextStream cout(stdout, QIODevice::WriteOnly);
// 	cout<<QString(xml)<<endl;
// 	cout<<url.path()<<endl;
    QHttpRequestHeader header("POST", url.path());
    // add the port from the URL if set
    header.setValue("Host", url.host() + QString(":")+ QString::number(url.port()));
// 	cout<<"header value: "<<header.value("Host")<<endl;
	//if a username is present, then add Basic authentication Header
    if(url.userName().length() > 0) {
        header.setValue("Authorization", "Basic " + (url.userName().append(":").append(url.password())).toAscii().toBase64());
    }
    header.setValue("User-Agent", "QxtXmlRpc");
    header.setValue("Content-Type", "text/xml");
    QIODevice* dev = new QBuffer();
    int req = http->request(header, xml, dev);
    requests[req] = dev;
    return req;
}

void QxtXmlRpcClient::handleResponse(int req, bool error) {
    if (error) {
        // throw error
        qDebug("an error occured");
        QIODevice* dev = requests.take(req);
        dev->close();
        delete dev;
        emit(networkError(req, http->errorString()));
    }
    if (requests.keys().contains( req )) {
        QIODevice* dev = requests.take(req);
        dev->close();
        dev->open( QIODevice::ReadOnly );
        QByteArray data = dev->readAll();
        delete dev;
        QList<QVariant> args;
        QString sdata = QString::fromUtf8( data );
        try {
            QxtXmlRpcResponseParser rp(sdata);
            emit(finished( req, rp.returnValue() ));
        } catch (QxtXmlRpcFault f) {
            emit(fault(req, f.faultCode(), f.faultString()));
        } catch (QxtXmlRpcParseError e) {
            emit(parseError(req, e.errorMsg()));
        }
    }
}


