#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ctype.h>
#include <mach.h>
#define Extern extern
#include "acid.h"
#include "y.tab.h"

static void install(int);

void
sproc(int xpid)
{
	Lsym *s;
	int i;

	if(symmap == 0)
		error("no map");

	if(pid == xpid)
		return;

	if(corhdr){
		free(correg);
		correg = nil;
		correg = coreregs(corhdr, xpid);
		if(correg == nil)
			error("no such pid in core dump");
	}else{
		/* XXX should only change register set here if cormap already mapped */		
		if(xpid <= 0)
			error("bad pid");
		unmapproc(cormap);
		unmapfile(corhdr, cormap);
		free(correg);
		correg = nil;

		if(mapproc(xpid, cormap, &correg) < 0)
			error("setproc %d: %r", xpid);

		/* XXX check text file here? */

		for(i=0; i<cormap->nseg; i++){
			if(cormap->seg[i].file == nil){
				if(strcmp(cormap->seg[i].name, "data") == 0)
					cormap->seg[i].name = "*data";
				if(strcmp(cormap->seg[i].name, "text") == 0)
					cormap->seg[i].name = "*text";
			}
		}
	}
	pid = xpid;
	s = look("pid");
	s->v->store.u.ival = pid;

	install(pid);
}

int
nproc(char **argv)
{
	int pid, i;

	pid = fork();
	switch(pid) {
	case -1:
		error("new: fork %r");
	case 0:
		rfork(RFNAMEG|RFNOTEG);
		if(ctlproc(getpid(), "hang") < 0)
			fatal("new: hang %d: %r", getpid());

		close(0);
		close(1);
		close(2);
		for(i = 3; i < NFD; i++)
			close(i);

		open("/dev/tty", OREAD);
		open("/dev/tty", OWRITE);
		open("/dev/tty", OWRITE);
		exec(argv[0], argv);
		fatal("new: exec %s: %r");
	default:
		install(pid);
		msg(pid, "waitstop");
		notes(pid);
		sproc(pid);
		dostop(pid);
		break;
	}

	return pid;
}

void
notes(int pid)
{
	Lsym *s;
	Value *v;
	int i, n;
	char **notes;
	List *l, **tail;

	s = look("notes");
	if(s == 0)
		return;

	v = s->v;
	n = procnotes(pid, &notes);
	if(n < 0)
		error("procnotes pid=%d: %r", pid);

	v->set = 1;
	v->type = TLIST;
	v->store.u.l = 0;
	tail = &v->store.u.l;
	for(i=0; i<n; i++) {
		l = al(TSTRING);
		l->store.u.string = strnode(notes[i]);
		l->store.fmt = 's';
		*tail = l;
		tail = &l->next;
	}
	free(notes);
}

void
dostop(int pid)
{
	Lsym *s;
	Node *np, *p;

	s = look("stopped");
	if(s && s->proc) {
		np = an(ONAME, ZN, ZN);
		np->sym = s;
		np->store.fmt = 'D';
		np->type = TINT;
		p = con(pid);
		p->store.fmt = 'D';
		np = an(OCALL, np, p);
		execute(np);
	}
}

static void
install(int pid)
{
	Lsym *s;
	List *l;
	int i, new, p;

	new = -1;
	for(i = 0; i < Maxproc; i++) {
		p = ptab[i].pid;
		if(p == pid)
			return;
		if(p == 0 && new == -1)
			new = i;
	}
	if(new == -1)
		error("no free process slots");

	ptab[new].pid = pid;

	s = look("proclist");
	l = al(TINT);
	l->store.fmt = 'D';
	l->store.u.ival = pid;
	l->next = s->v->store.u.l;
	s->v->store.u.l = l;
	s->v->set = 1;
}

/*
static int
installed(int pid)
{
	int i;

	for(i=0; i<Maxproc; i++)
		if(ptab[i].pid == pid)
			return 1;
	return 0;
}
*/

void
deinstall(int pid)
{
	int i;
	Lsym *s;
	List *f, **d;

	for(i = 0; i < Maxproc; i++) {
		if(ptab[i].pid == pid) {
			detachproc(pid);
			// close(ptab[i].ctl);
			ptab[i].pid = 0;
			s = look("proclist");
			d = &s->v->store.u.l;
			for(f = *d; f; f = f->next) {
				if(f->store.u.ival == pid) {
					*d = f->next;
					break;
				}
			}
			s = look("pid");
			if(s->v->store.u.ival == pid)
				s->v->store.u.ival = 0;
			return;
		}
	}
}

void
msg(int pid, char *msg)
{
	int i;
	char err[ERRMAX];

	for(i = 0; i < Maxproc; i++) {
		if(ptab[i].pid == pid) {
			if(ctlproc(pid, msg) < 0){
				errstr(err, sizeof err);
				if(strcmp(err, "process exited") == 0)
					deinstall(pid);
				error("msg: pid=%d %s: %s", pid, msg, err);
			}
			return;
		}
	}
	error("msg: pid=%d: not found for %s", pid, msg);
}

char *
getstatus(int pid)
{
	int fd;
	char *p;

	static char buf[128];

	sprint(buf, "/proc/%d/status", pid);
	fd = open(buf, OREAD);
	if(fd < 0)
		error("open %s: %r", buf);
	read(fd, buf, sizeof(buf));
	close(fd);
	p = buf+56+12;			/* Do better! */
	while(*p == ' ')
		p--;
	p[1] = '\0';
	return buf+56;			/* ditto */
}

