#include <u.h>
#include <libc.h>
#include <ip.h>
#include <bio.h>
#include <ndb.h>

static uchar noether[6];

/*
 *  Look for a pair with the given attribute.  look first on the same line,
 *  then in the whole entry.
 */
static Ndbtuple*
lookval(Ndbtuple *entry, Ndbtuple *line, char *attr, char *to)
{
	Ndbtuple *nt;

	/* first look on same line (closer binding) */
	for(nt = line;;){
		if(strcmp(attr, nt->attr) == 0){
			strncpy(to, nt->val, Ndbvlen);
			return nt;
		}
		nt = nt->line;
		if(nt == line)
			break;
	}
	/* search whole tuple */
	for(nt = entry; nt; nt = nt->entry)
		if(strcmp(attr, nt->attr) == 0){
			strncpy(to, nt->val, Ndbvlen);
			return nt;
		}
	return 0;
}

/*
 *  lookup an ip address
 */
static uchar*
lookupip(Ndb *db, char *name, uchar *to, Ipinfo *iip)
{
	Ndbtuple *t, *nt;
	char buf[Ndbvlen];
	uchar subnet[IPaddrlen];
	Ndbs s;
	char *attr;

	attr = ipattr(name);
	if(strcmp(attr, "ip") == 0){
		parseip(to, name);
		return to;
	}

	t = ndbgetval(db, &s, attr, name, "ip", buf);
	if(t){
		/* first look for match on same subnet */
		for(nt = t; nt; nt = nt->entry){
			if(strcmp(nt->attr, "ip") != 0)
				continue;
			parseip(to, nt->val);
			maskip(to, iip->ipmask, subnet);
			if(memcmp(subnet, iip->ipnet, sizeof(subnet)) == 0)
				return to;
		}

		/* otherwise, just take what we have */
		ndbfree(t);
		parseip(to, buf);
		return to;
	}
	return 0;
}

/*
 *  lookup a subnet and fill in anything we can
 */
static void
recursesubnet(Ndb *db, uchar *mask, Ipinfo *iip, char *fs, char *gw, char *au)
{
	Ndbs s;
	Ndbtuple *t;
	uchar submask[IPaddrlen];
	char ip[Ndbvlen];

	memmove(iip->ipmask, mask, 4);
	maskip(iip->ipaddr, iip->ipmask, iip->ipnet);
	sprint(ip, "%I", iip->ipnet);
	t = ndbsearch(db, &s, "ip", ip);
print("%s->", ip);
	if(t){
		/* look for a further subnet */
		if(lookval(t, s.t, "ipmask", ip)){
			parseip(submask, ip);

			/* recurse only if it has changed */
			if(!equivip(submask, mask))
				recursesubnet(db, submask, iip, fs, gw, au);

		}

		/* fill in what we don't have */
		if(gw[0] == 0)
			lookval(t, s.t, "ipgw", gw);
		if(fs[0] == 0)
			lookval(t, s.t, "fs", fs);
		if(au[0] == 0)
			lookval(t, s.t, "auth", au);

		ndbfree(t);
	}
}
#ifdef foo
/*
 *  find out everything we can about a system from what has been
 *  specified.
 */
int
ipinfo(Ndb *db, char *etherin, char *ipin, char *name, Ipinfo *iip)
{
	Ndbtuple *t;
	Ndbs s;
	char ether[Ndbvlen];
	char ip[Ndbvlen];
	char fsname[Ndbvlen];
	char gwname[Ndbvlen];
	char auname[Ndbvlen];

	memset(iip, 0, sizeof(Ipinfo));
	fsname[0] = 0;
	gwname[0] = 0;
	auname[0] = 0;

	/*
	 *  look for a matching entry
	 */
	t = 0;
	if(etherin)
		t = ndbgetval(db, &s, "ether", etherin, "ip", ip);
	if(t == 0 && ipin)
		t = ndbsearch(db, &s, "ip", ipin);
	if(t == 0 && name)
		t = ndbgetval(db, &s, ipattr(name), name, "ip", ip);
	if(t){
		/*
		 *  copy in addresses and name
		 */
		if(lookval(t, s.t, "ip", ip))
			parseip(iip->ipaddr, ip);
		if(lookval(t, s.t, "ether", ether))
			parseether(iip->etheraddr, ether);
		lookval(t, s.t, "dom", iip->domain);

		/*
		 *  Look for bootfile, fs, and gateway.
		 *  If necessary, search through all entries for
		 *  this ip address.
		 */
		while(t){
			if(iip->bootf[0] == 0)
				lookval(t, s.t, "bootf", iip->bootf);
			if(fsname[0] == 0)
				lookval(t, s.t, "fs", fsname);
			if(gwname[0] == 0)
				lookval(t, s.t, "ipgw", gwname);
			if(auname[0] == 0)
				lookval(t, s.t, "auth", auname);
			ndbfree(t);
			if(iip->bootf[0] && fsname[0] && gwname[0] && auname[0])
				break;
			t = ndbsnext(&s, "ether", ether);
		}
	} else if(ipin) {
		/*
		 *  copy in addresses (all we know)
		 */
		parseip(iip->ipaddr, ipin);
		if(etherin)
			parseether(iip->etheraddr, etherin);
	} else
		return -1;

	/*
	 *  Look up the client's network and find a subnet mask for it.
	 *  Fill in from the subnet (or net) entry anything we can't figure
	 *  out from the client record.
	 */
	recursesubnet(db, classmask[CLASS(iip->ipaddr)], iip, fsname, gwname, auname);

	/* lookup fs's and gw's ip addresses */
	
	if(fsname[0])
		lookupip(db, fsname, iip->fsip, iip);
	if(gwname[0])
		lookupip(db, gwname, iip->gwip, iip);
	if(auname[0])
		lookupip(db, auname, iip->auip, iip);
	return 0;
}
#endif
void
main(int argc, char **argv)
{
	Ipinfo ii;
	Ndb *db;

	db = ndbopen(0);

	fmtinstall('E', eipconv);
	fmtinstall('I', eipconv);
	if(argc < 2)
		exits(0);
	if(strchr(argv[1], '.')){
		if(ipinfo(db, 0, argv[1], 0, &ii) < 0)
			exits(0);
	} else {
		if(ipinfo(db, argv[1], 0, 0, &ii) < 0)
			exits(0);
	}
	fprint(2, "a %I m %I n %I f %s e %E\n", ii.ipaddr,
		ii.ipmask, ii.ipnet, ii.bootf, ii.etheraddr);
}
