#include <u.h>
#define NOPLAN9DEFINES
#include <libc.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/un.h>
#include <netinet/in.h>

static char *nets[] = { "tcp", "udp", nil };
#define CLASS(p) ((*(uchar*)(p))>>6)

static struct {
	char *net;
	char *service;
	int port;
} porttbl[] = {
	"tcp",	"9fs",	564,
	"tcp",	"whoami",	565,
	"tcp",	"guard",	566,
	"tcp",	"ticket",	567,
	"tcp",	"exportfs",	17007,
	"tcp",	"rexexec",	17009,
	"tcp",	"ncpu",	17010,
	"tcp",	"cpu",	17013,
	"tcp",	"venti",	17034,
	"tcp",	"wiki",	17035,
	"tcp",	"secstore",	5356,
	"udp",	"dns",	53,
	"tcp",	"dns",	53,
};

static int
setport(struct sockaddr_storage *ss, int port)
{
	switch(ss->ss_family){
	case AF_INET:
		((struct sockaddr_in*)ss)->sin_port = htons(port);
		break;
	case AF_INET6:
		((struct sockaddr_in6*)ss)->sin6_port = htons(port);
		break;
	default:
		errstr("unknown protocol family %d", ss->ss_family);
		return -1;
	}
	return 0;
}

int
p9dialparse(char *addr, char **pnet, char **punix, void *phost, int *pport)
{
	char *net, *host, *port, *e;
	int i;
	struct servent *se;
	struct hostent *he;
	struct sockaddr_storage *ss;
	struct addrinfo *result;

	ss = phost;

	memset(ss, 0, sizeof *ss);

	*punix = nil;
	net = addr;
	if((host = strchr(net, '!')) == nil){
		werrstr("malformed address");
		return -1;
	}
	*host++ = 0;
	if((port = strchr(host, '!')) == nil){
		if(strcmp(net, "unix")==0 || strcmp(net, "net")==0){
		Unix:
			if(strlen(host)+1 > sizeof ((struct sockaddr_un*)&ss)->sun_path){
				werrstr("unix socket name too long");
				return -1;
			}
			*punix = host;
			*pnet = "unix";
			ss->ss_family = AF_UNIX;
			strcpy(((struct sockaddr_un*)ss)->sun_path, host);
			*pport = 0;
			return 0;
		}
		werrstr("malformed address");
		return -1;
	}
	*port++ = 0;

	if(*host == 0){
		werrstr("malformed address (empty host)");
		return -1;
	}
	if(*port == 0){
		werrstr("malformed address (empty port)");
		return -1;
	}

	if(strcmp(net, "unix") == 0)
		goto Unix;

	if(strcmp(net, "tcp")!=0 && strcmp(net, "udp")!=0 && strcmp(net, "net") != 0){
		werrstr("bad network %s!%s!%s", net, host, port);
		return -1;
	}

	/* translate host */
	if(strcmp(host, "*") == 0){
		ss->ss_family = AF_INET6;
		((struct sockaddr_in6*)ss)->sin6_addr = in6addr_any;
	}else if((he = gethostbyname(host)) != nil && he->h_addr_list[0] != nil){
		ss->ss_family = he->h_addrtype;
		switch(ss->ss_family){
		case AF_INET:
			((struct sockaddr_in*)ss)->sin_addr = *(struct in_addr*) *(he->h_addr_list);
			break;
		case AF_INET6:
			((struct sockaddr_in6*)ss)->sin6_addr = *(struct in6_addr*) *(he->h_addr_list);
			break;
		default:
			errstr("unknown protocol family %d", ss->ss_family);
			return -1;
		}
	}else if(getaddrinfo(host, NULL, NULL, &result) == 0) {
		switch (result->ai_family) {
		case AF_INET:
			memmove((struct sockaddr_in*)ss, result->ai_addr, result->ai_addrlen);
			break;
		case AF_INET6:
			memmove((struct sockaddr_in6*)ss, result->ai_addr, result->ai_addrlen);
			break;
		default:
			errstr("unknown protocol family %d", ss->ss_family);
			return -1;
		}
	}else{
		werrstr("unknown host %s", host);
		return -1;
	}

	/* translate network and port; should return list rather than first */
	if(strcmp(net, "net") == 0){
		for(i=0; nets[i]; i++){
			if((se = getservbyname(port, nets[i])) != nil){
				*pnet = nets[i];
				*pport = ntohs(se->s_port);
				return setport(ss, *pport);
			}
		}
	}

	for(i=0; i<nelem(porttbl); i++){
		if(strcmp(net, "net") == 0 || strcmp(porttbl[i].net, net) == 0)
		if(strcmp(porttbl[i].service, port) == 0){
			*pnet = porttbl[i].net;
			*pport = porttbl[i].port;
			return setport(ss, *pport);
		}
	}

	if(strcmp(net, "net") == 0){
		werrstr("unknown service net!*!%s", port);
		return -1;
	}

	if(strcmp(net, "tcp") != 0 && strcmp(net, "udp") != 0){
		werrstr("unknown network %s", net);
		return -1;
	}

	*pnet = net;
	i = strtol(port, &e, 0);
	if(*e == 0){
		*pport = i;
		return setport(ss, *pport);
	}

	if((se = getservbyname(port, net)) != nil){
		*pport = ntohs(se->s_port);
		return setport(ss, *pport);
	}
	werrstr("unknown service %s!*!%s", net, port);
	return -1;
}
