#include "std.h"
#include "dat.h"

Ring ring;

Key*
keylookup(char *fmt, ...)
{
	int i;
	Attr *a;
	Key *k;
	va_list arg;

	va_start(arg, fmt);
	a = parseattrfmtv(fmt, arg);
	va_end(arg);

	for(i=0; i<ring.nkey; i++){
		k = ring.key[i];
		if(matchattr(a, k->attr, k->privattr)){
			k->ref++;
			freeattr(a);
			return k;
		}
	}
	freeattr(a);
	werrstr("no key found");
	return nil;
}

Key*
keyfetch(Conv *c, char *fmt, ...)
{
	int i, tag;
	Attr *a;
	Key *k;
	va_list arg;

	va_start(arg, fmt);
	a = parseattrfmtv(fmt, arg);
	va_end(arg);

	tag = 0;

	for(i=0; i<ring.nkey; i++){
		k = ring.key[i];
		if(tag < k->tag)
			tag = k->tag;
		if(matchattr(a, k->attr, k->privattr)){
			k->ref++;
			if(strfindattr(k->attr, "confirm") && confirmkey(c, k) != 1){
				k->ref--;
				continue;
			}
			freeattr(a);
			return k;
		}
	}

	if(needkey(c, a) < 0)
		convneedkey(c, a);

	for(i=0; i<ring.nkey; i++){
		k = ring.key[i];
		if(k->tag <= tag)
			continue;
		if(matchattr(a, k->attr, k->privattr)){
			k->ref++;
			if(strfindattr(k->attr, "confirm") && confirmkey(c, k) != 1){
				k->ref--;
				continue;
			}
			freeattr(a);
			return k;
		}
	}
	freeattr(a);
	werrstr("no key found");
	return nil;
}

static int taggen;

void
keyadd(Key *k)
{
	int i;

	k->ref++;
	k->tag = ++taggen;
	for(i=0; i<ring.nkey; i++){
		if(matchattr(k->attr, ring.key[i]->attr, nil)
		&& matchattr(ring.key[i]->attr, k->attr, nil)){
			keyclose(ring.key[i]);
			ring.key[i] = k;
			return;
		}
	}

	ring.key = erealloc(ring.key, (ring.nkey+1)*sizeof(ring.key[0]));
	ring.key[ring.nkey++] = k;
}

void
keyclose(Key *k)
{
	if(k == nil)
		return;

	if(--k->ref > 0)
		return;

	if(k->proto->closekey)
		(*k->proto->closekey)(k);

	freeattr(k->attr);
	freeattr(k->privattr);
	free(k);
}

Key*
keyreplace(Conv *c, Key *k, char *fmt, ...)
{
	Key *kk;
	char *msg;
	Attr *a, *b, *bp;
	va_list arg;

	va_start(arg, fmt);
	msg = vsmprint(fmt, arg);
	if(msg == nil)
		sysfatal("out of memory");
	va_end(arg);

	/* replace prompted values with prompts */	
	a = copyattr(k->attr);
	bp = parseattr(k->proto->keyprompt);
	for(b=bp; b; b=b->next){
		a = delattr(a, b->name);
		a = addattr(a, "%q?", b->name);
	}
	freeattr(bp);

	if(badkey(c, k, msg, a) < 0)
		convbadkey(c, k, msg, a);
	kk = keylookup("%A", a);
	freeattr(a);
	keyclose(k);
	if(kk == k){
		keyclose(kk);
		werrstr("%s", msg);
		return nil;
	}

	if(strfindattr(kk->attr, "confirm")){
		if(confirmkey(c, kk) != 1){
			werrstr("key use not confirmed");
			keyclose(kk);
			return nil;
		}
	}
	return kk;
}

void
keyevict(Conv *c, Key *k, char *fmt, ...)
{
	char *msg;
	Attr *a, *b, *bp;
	va_list arg;

	va_start(arg, fmt);
	msg = vsmprint(fmt, arg);
	if(msg == nil)
		sysfatal("out of memory");
	va_end(arg);

	/* replace prompted values with prompts */	
	a = copyattr(k->attr);
	bp = parseattr(k->proto->keyprompt);
	for(b=bp; b; b=b->next){
		a = delattr(a, b->name);
		a = addattr(a, "%q?", b->name);
	}
	freeattr(bp);

	if(badkey(c, k, msg, nil) < 0)
		convbadkey(c, k, msg, nil);
	keyclose(k);
}
