#include <u.h>
#include <libc.h>
#define NODEFINE
#include "dat.h"

static char*
rdenv(char *name)
{
	char *v;
	int fd, size;

	fd = open(name, OREAD);
	if(fd < 0)
		return 0;
	size = seek(fd, 0, 2);
	v = malloc(size+1);
	if(v == 0)
		return nil;
	seek(fd, 0, 0);
	read(fd, v, size);
	v[size] = 0;
	close(fd);
	return v;
}

static int
newwin(void)
{
	char *srv, *mntsrv;
	char spec[100];
	int srvfd;

	srv = rdenv("/env/wsys");
	if(srv == 0){
		mntsrv = rdenv("/mnt/term/env/wsys");
		if(mntsrv == 0){
			fprint(2, "factotum: can't find $wsys\n");
			return -1;
		}
		srv = malloc(strlen(mntsrv)+10);
		strcpy(srv, "/mnt/term");
		strcat(srv, mntsrv);
		free(mntsrv);
	}

	srvfd = open(srv, ORDWR);
	free(srv);
	if(srvfd == -1){
		fprint(2, "factotum: can't open %s: %r\n", srv);
		return -1;
	}
	sprint(spec, "new", getpid());
	if(mount(srvfd, -1, "/mnt/temp", 0, spec) == -1){
		close(srvfd);
		fprint(2, "factotum: can't mount /mnt/wsys: %r (spec=%s)\n", spec);
		return -1;
	}
	close(srvfd);
	return 0;
}

/*
 *  prompt for a string with a possible default response
 */
String*
readcons(char *prompt, char *def, int raw)
{
	int fdin, fdout, ctl, n;
	char line[10];
	String *s = s_new();

	if(newwin() < 0)
		return nil;

	fdin = open("/mnt/temp/cons", OREAD);
	if(fdin < 0)
		fdin = 0;
	fdout = open("/mnt/temp/cons", OWRITE);
	if(fdout < 0)
		fdout = 1;
	if(def != nil)
		fprint(fdout, "%s[%s]: ", prompt, def);
	else
		fprint(fdout, "%s: ", prompt);
	if(raw){
		ctl = open("/mnt/temp/consctl", OWRITE);
		if(ctl >= 0)
			write(ctl, "rawon", 5);
	} else
		ctl = -1;
	for(;;){
		n = read(fdin, line, 1);
		if(n == 0){
		Error:
			close(fdin);
			close(fdout);
			if(ctl >= 0)
				close(ctl);
			s_free(s);
			unmount(nil, "/mnt/temp");
			return nil;
		}
		if(n < 0)
			goto Error;
		if(line[0] == 0x7f)
			goto Error;
		if(n == 0 || line[0] == '\n' || line[0] == '\r'){
			if(raw){
				write(ctl, "rawoff", 6);
				write(fdout, "\n", 1);
			}
			close(ctl);
			close(fdin);
			close(fdout);
			s_terminate(s);
			if(*s_to_c(s) == 0 && def != nil)
				s_append(s, def);
			unmount(nil, "/mnt/temp");
			return s;
		}
		if(line[0] == '\b'){
			if(s_len(s) > 0)
				s->ptr--;
		} else if(line[0] == 0x15) {	/* ^U: line kill */
			s_reset(s);
		} else {
			s_putc(s, line[0]);
		}
	}
	abort();
	return nil;	/* how does this happen */
}

