#include <u.h>
#include <libc.h>
#include <venti.h>

int ventidoublechecksha1 = 1;

static int
vtfcallrpc(VtConn *z, VtFcall *ou, VtFcall *in)
{
	Packet *p;

	p = vtfcallpack(ou);
	if(p == nil)
		return -1;
	if((p = _vtrpc(z, p, ou)) == nil)
		return -1;
	if(vtfcallunpack(in, p) < 0){
		packetfree(p);
		return -1;
	}
	if(chattyventi)
		fprint(2, "%s <- %F\n", argv0, in);
	if(in->msgtype == VtRerror){
		werrstr(in->error);
		vtfcallclear(in);
		packetfree(p);
		return -1;
	}
	if(in->msgtype != ou->msgtype+1){
		werrstr("type mismatch: sent %c%d got %c%d",
			"TR"[ou->msgtype&1], ou->msgtype>>1,
			"TR"[in->msgtype&1], in->msgtype>>1);
		vtfcallclear(in);
		packetfree(p);
		return -1;
	}
	packetfree(p);
	return 0;
}

int
vthello(VtConn *z)
{
	VtFcall tx, rx;

	memset(&tx, 0, sizeof tx);
	tx.msgtype = VtThello;
	tx.version = z->version;
	tx.uid = z->uid;
	if(tx.uid == nil)
		tx.uid = "anonymous";
	if(vtfcallrpc(z, &tx, &rx) < 0)
		return -1;
	z->sid = rx.sid;
	rx.sid = 0;
	vtfcallclear(&rx);
	return 0;
}

Packet*
vtreadpacket(VtConn *z, uchar score[VtScoreSize], uint type, int n)
{
	VtFcall tx, rx;

	if(memcmp(score, vtzeroscore, VtScoreSize) == 0)
		return packetalloc();

	if(z->version[1] == '2' && n >= (1<<16)) {
		werrstr("read count too large for protocol");
		return nil;
	}
	memset(&tx, 0, sizeof tx);
	tx.msgtype = VtTread;
	tx.blocktype = type;
	tx.count = n;
	memmove(tx.score, score, VtScoreSize);
	if(vtfcallrpc(z, &tx, &rx) < 0)
		return nil;
	if(packetsize(rx.data) > n){
		werrstr("read returned too much data");
		packetfree(rx.data);
		return nil;
	}
	if(ventidoublechecksha1){
		packetsha1(rx.data, tx.score);
		if(memcmp(score, tx.score, VtScoreSize) != 0){
			werrstr("read asked for %V got %V", score, tx.score);
			packetfree(rx.data);
			return nil;
		}
	}
	return rx.data;
}

int
vtread(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
{
	int nn;
	Packet *p;

	if((p = vtreadpacket(z, score, type, n)) == nil)
		return -1;
	nn = packetsize(p);
	if(packetconsume(p, buf, nn) < 0)
		abort();
	packetfree(p);
	return nn;
}

int
vtwritepacket(VtConn *z, uchar score[VtScoreSize], uint type, Packet *p)
{
	VtFcall tx, rx;

	if(packetsize(p) == 0){
		memmove(score, vtzeroscore, VtScoreSize);
		return 0;
	}
	tx.msgtype = VtTwrite;
	tx.blocktype = type;
	tx.data = p;
	if(ventidoublechecksha1)
		packetsha1(p, score);
	if(vtfcallrpc(z, &tx, &rx) < 0)
		return -1;
	if(ventidoublechecksha1){
		if(memcmp(score, rx.score, VtScoreSize) != 0){
			werrstr("sha1 hash mismatch: want %V got %V", score, rx.score);
			return -1;
		}
	}else
		memmove(score, rx.score, VtScoreSize);
	return 0;
}

int
vtwrite(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
{
	Packet *p;
	int nn;

	p = packetforeign(buf, n, 0, nil);
	nn = vtwritepacket(z, score, type, p);
	packetfree(p);
	return nn;
}

int
vtsync(VtConn *z)
{
	VtFcall tx, rx;

	tx.msgtype = VtTsync;
	return vtfcallrpc(z, &tx, &rx);
}

int
vtping(VtConn *z)
{
	VtFcall tx, rx;

	tx.msgtype = VtTping;
	return vtfcallrpc(z, &tx, &rx);
}

int
vtconnect(VtConn *z)
{
	if(vtversion(z) < 0)
		return -1;
	if(vthello(z) < 0)
		return -1;
	return 0;
}

int
vtgoodbye(VtConn *z)
{
	VtFcall tx, rx;
	
	tx.msgtype = VtTgoodbye;
	vtfcallrpc(z, &tx, &rx);	/* always fails: no VtRgoodbye */
	return 0;
}
