/***************************************************************************
*   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 "localnode.h"
#include "nodeid.h"

#include <QHostAddress>
#include <QReadWriteLock>

namespace KRPC
{
}

KRPC::LocalNode::LocalNode( const QHostAddress &host, unsigned port )
: BasicNode( host, port ), m_host(host), m_port(port)
{
	m_lock = new QReadWriteLock;
	m_key = NodeID( m_host.toString().toLatin1() + QByteArray::number(m_port) );
	put(m_key,this);
}


KRPC::LocalNode::~LocalNode()
{
	delete m_lock;
}


KRPC::NodeID KRPC::LocalNode::key() const
{
	return m_key;
}

KRPC::NodeID KRPC::LocalNode::lowerKey() const
{
	QReadLocker lock( m_lock );
	NodeID minKey = m_lookupTable.keys().first();
	foreach( NodeID key, m_lookupTable.keys() )
	{
		minKey = qMin(key, minKey);
	}
	return minKey;
}

KRPC::NodeID KRPC::LocalNode::nextKey() const
{
	QReadLocker lock( m_lock );
	QMap<NodeID,NodeInterface*>::const_iterator idx = m_lookupTable.find(key());
	if( idx + 1 != m_lookupTable.end() )
		++idx;
	return idx.key();
}

KRPC::NodeID KRPC::LocalNode::previousKey() const
{
	QReadLocker lock( m_lock );
	QMap<NodeID,NodeInterface*>::const_iterator idx = m_lookupTable.find(key());
	if( idx != m_lookupTable.begin() )
	{
		--idx;
	}
	return idx.key();
}

KRPC::NodeID KRPC::LocalNode::upperKey() const
{
	QReadLocker lock( m_lock );
	NodeID maxKey = m_lookupTable.keys().first();
	foreach( NodeID key, m_lookupTable.keys() )
	{
		maxKey = qMax(key, maxKey);
	}
	return maxKey;
}

KRPC::NodeInterface *KRPC::LocalNode::get( const KRPC::NodeID& key ) const
{
	QReadLocker lock( m_lock );
	return m_lookupTable[key];
}

void KRPC::LocalNode::put( const KRPC::NodeID& key, NodeInterface *node )
{
	QWriteLocker lock( m_lock );
	m_lookupTable.insert( key, node );
}

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

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

bool KRPC::LocalNode::hasKey( const NodeID & key ) const
{
	QReadLocker lock( m_lock );
	return m_lookupTable.contains(key);
}

