#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>
#include <time.h>
#include <sys/file.h>
#include <netdb.h>
#include <sys/socket.h>

#include "node.h"

static char buf[4096];

int nputs(const char *str)
{
	return axio_puts(str, NodeIo);
}

int nprintf(const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	vsprintf(buf, fmt, args);
	va_end(args);

	return nputs(buf);
}

void node_msg(const char *fmt, ...)
{
	va_list args;
	
	va_start(args, fmt);
	vsprintf(buf, fmt, args);
	va_end(args);

	nputs(NodeId);
	nputs(" ");
	nputs(buf);
	nputs("\n");
}

void node_perror(char *str, int err)
{
	int oldmode;

	oldmode = axio_eolmode(NodeIo, EOLMODE_TEXT);
	buf[0] = 0;
	if (str)
		strcpy(buf, str);
	if (str && err != -1)
		strcat(buf, ": ");
	if (err != -1)
		strcat(buf, strerror(err));

	nputs(NodeId);
	nputs(" ");
	nputs(buf);
	nputs("\n");

	axio_flush(NodeIo);
	axio_eolmode(NodeIo, oldmode);
	log(L_ERROR, buf);
}

char *print_node(const char *alias, const char *call)
{
	static char node[17];

	sprintf(node, "%s%s%s",
		!strcmp(alias, "*") ? "" : alias,
		!strcmp(alias, "*") ? "" : ":",
		call);
	return node;
}

char *print_dl(struct user *u)
{
	static char buf[64];

	switch (u->dl_type) {
	case AF_AX25:
		sprintf(buf, "%s on port %s", u->dl_name, u->dl_port);
		break;
	case AF_NETROM:
	case AF_ROSE:
                sprintf(buf, "%s", u->dl_name);
		break;
	case AF_INET:
		sprintf(buf, "%s:%s", u->dl_name, u->dl_port);
		break;
	}
	return buf;
}

void put_prompt(void)
{
	char *p;

	if (strchr(NodePrompt, '%') == NULL) {
		nputs(NodePrompt);
		return;
	}
	p = expand_string(NodePrompt, 0, NULL);
	nputs(p);
	free(p);
}

void log(int loglevel, const char *fmt, ...)
{
	va_list args;
	int pri;
	static int opened = 0;

	if (LogLevel < loglevel)
		return;
	if (!opened) {
		openlog("node", LOG_PID, LOG_LOCAL7);
		opened = 1;
	}
	switch (loglevel) {
	case L_ERROR:
		pri = LOG_ERR;
		break;
	case L_LOGIN:
		pri = LOG_NOTICE;
		break;
	case L_GW:
		pri = LOG_INFO;
		break;
	default:
		pri = LOG_INFO;
		break;
	}
	va_start(args, fmt);
	vsprintf(buf, fmt, args);
	syslog(pri, buf);
	va_end(args);
}

char *strherror(int err)
{
	static char buf[64];

	switch (err) {
	case HOST_NOT_FOUND:
		strcpy(buf, "Unknown host");
		break;
	case TRY_AGAIN:
		strcpy(buf, "Temporary name server error");
		break;
	case NO_RECOVERY:
		strcpy(buf, "Non-recoverable name server error");
		break;
	case NO_ADDRESS:
		strcpy(buf, "No address");
		break;
	default:
		strcpy(buf, "Unknown error");
		break;
	}
	return buf;
}
