/***************************************************************************
*   Copyright (C) 2006 by Ian Reinhart Geiser   *
*   geiseri@sourcextreme.com   *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU Library General Public License as       *
*   published by the Free Software Foundation; either version 2 of the    *
*   License, or (at your option) any later version.                       *
*                                                                         *
*   This program is distributed in the hope that it will be useful,       *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
*   GNU General Public License for more details.                          *
*                                                                         *
*   You should have received a copy of the GNU Library General Public     *
*   License along with this program; if not, write to the                 *
*   Free Software Foundation, Inc.,                                       *
*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
***************************************************************************/
#include "remotenode.h"
#include "nodeid.h"
#include "remotemethod.h"

#include <QHostAddress>
#include <QVariant>

namespace KRPC
{
}

KRPC::RemoteNode::RemoteNode( const QHostAddress &host, unsigned port )
: BasicNode( host, port ), m_host(host), m_port(port)
{
}


KRPC::RemoteNode::~RemoteNode()
{

}


KRPC::NodeID KRPC::RemoteNode::key() const
{
	return RemoteMethod::invoke(m_host, m_port, "/krpc/directory", "key").value<NodeID>();
	// get remote key  krpc://host:port/krpc/directory/key
}

KRPC::NodeID KRPC::RemoteNode::lowerKey() const
{
	return RemoteMethod::invoke(m_host, m_port, "/krpc/directory", "lowerKey").value<NodeID>();
	// get remote lower key krpc://host:port/krpc/directory/lowerKey
}

KRPC::NodeID KRPC::RemoteNode::nextKey() const
{
	return RemoteMethod::invoke(m_host, m_port, "/krpc/directory", "nextKey").value<NodeID>();
	// get remote next key krpc://host:port/krpc/directory/nextKey
}

KRPC::NodeID KRPC::RemoteNode::previousKey() const
{
	return RemoteMethod::invoke(m_host, m_port, "/krpc/directory", "previousKey").value<NodeID>();
	// get remote previous key krpc://host:port/krpc/directory/previousKey
}

KRPC::NodeID KRPC::RemoteNode::upperKey() const
{
	return RemoteMethod::invoke(m_host, m_port, "/krpc/directory", "upperKey").value<NodeID>();
	// get remote upper key krpc://host:port/krpc/directory/upperKey
}

KRPC::NodeInterface *KRPC::RemoteNode::get( const KRPC::NodeID& key ) const
{
	QMap<QString,QVariant> node = RemoteMethod::invoke(m_host, m_port,
		"/krpc/directory", "get", qVariantFromValue (key) ).value<QMap<QString, QVariant> >();
	//FIXME: This has got to be a memory leak!
	return new RemoteNode( QHostAddress( node["address"].value<QString>() ),
	                                     node["port"].value<uint>() );
	// get remote value of key krpc://host:port/krpc/directory/get
}

void KRPC::RemoteNode::put( const KRPC::NodeID& key, NodeInterface *node )
{
	QMap<QString,QVariant> nodeArg;
	nodeArg["address"] = node->address().toString();
	nodeArg["port"] = node->port();
	RemoteMethod::invoke(m_host, m_port,
	                     "/krpc/directory", "put",  qVariantFromValue (key), nodeArg );
	// put remote value on a node at key krpc://host:port/krpc/directory/put
}

unsigned int KRPC::RemoteNode::port( ) const
{
	return m_port;
}

QHostAddress KRPC::RemoteNode::address( ) const
{
	return m_host;
}

bool KRPC::RemoteNode::hasKey( const NodeID & key ) const
{
	return RemoteMethod::invoke(m_host, m_port,
	                     "/krpc/directory", "hasKey", key.toString() ).value< bool >();
}

