#include "SH_network_types.h"
#include "SH_server_base.h"
#include <pisysteminfo.h>
#include <pichunkstream.h>
#include <piiodevice.h>
#include "ccm_SHS_shared.h"


PIByteArray SHNetworkTypes::makeHeader(int t) {
	PacketHeader h(t);
	return PIByteArray(&h, sizeof(h));
}


PacketHeader SHNetworkTypes::takeHeader(PIByteArray & ba) {
	PacketHeader ret;
	if (ba.size() < sizeof(ret)) return ret;
	memcpy(&ret, ba.data(), sizeof(ret));
	ba.remove(0, sizeof(ret));
	return ret;
}




PacketHeader::PacketHeader(int t) {
	type = t;
}




PacketIdentification::PacketIdentification() {
	net_version = sync_version = 0;
	os_type = SHPlatform::Unknown;
	role = 0;
	machine_id = 0;
}


PacketIdentification PacketIdentification::makeLocal(int r, int net_version, int sync_version) {
	PacketIdentification ret;
	ret.role = r;
	ret.os_type = thisOS();
	ret.arch = thisArch();
	ret.machine_id = PISystemInfo::machineID();
	ret.os_version = PISystemInfo::instance()->OS_version;
	ret.hostname   = PISystemInfo::instance()->hostname;
	ret.net_version  = net_version;
	ret.sync_version = sync_version;
	ret.shs_version  = SHS_VERSION_NAME;
	return ret;
}




PacketMessage::PacketMessage(int ty, const PIString & te, const PIDateTime & tm) {
	type = ty;
	text = te;
	time = tm;
}


bool PacketMessage::isValid() const {
	return type >= 0;
}


bool PacketServerInfo::isValid() const {
	return identify.os_type != SHPlatform::Unknown;
}


void PacketServerInfo::setUserRoles(const QVector<SHS::UserRole> roles) {
	user_roles.clear();
	ServerUserRole sr;
	for (const auto & r: roles) {
		sr.name = r.name;
		sr.display_name = r.display_name;
		sr.privilege = r.privilege;
		sr.index = r.index;
		user_roles << sr;
	}
}


PIByteArray PacketServerInfo::toByteArray() const {
	PIByteArray ret;
	ret << *this;
	return ret;
}


PIString PacketServerInfo::displayVersion() const {
	return "SHS:" + identify.shs_version +
		   ", UiSync: " + PIString::fromNumber(identify.sync_version) +
			", Net: " + PIString::fromNumber(identify.net_version);
}


bool PacketServerInfo::compatible() const {
	return (identify.net_version == SHS_NETWORK_VERSION) && (identify.sync_version == SHS_UISYNC_VERSION);
}


PacketServerInfo PacketServerInfo::fromByteArray(PIByteArray ba) {
	PacketServerInfo ret;
	ba >> ret;
	return ret;
}




ServerDevice::ServerDevice(const PIIODevice * d, const PIStringList & nl) {
	names = nl;
	if (d) fullpath = d->constructFullPath();
}


PIString ServerAddress::ipAddress() const {
	return Q2PIString(server + ':' + QString::number(port));
}


PIString ServerAddress::fullAddress() const {
	if (cloud_name.isEmpty()) return ipAddress();
	return ipAddress() + '@' + Q2PIString(cloud_name);
}


uint ServerAddress::hash() const {
	return fullAddress().hash();
}


QString ServerUserRole::displayName() const {
	if (!display_name.isEmpty()) return display_name;
	return name;
}
