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

struct nsline {
	struct nsline *next;
	char *tokens[5];
	char *fulline;
} ;

struct nslist {
	struct nsline *first;
	struct nsline *current;
	struct nsline *new;
} ;

struct listolists {
	struct listolists *next;
	struct nslist targlist;
	int nsof;
} ;

struct nslist makenslist(char *);

int main(int argc, char *argv[]){

	if (argc < 2){
		print("specify PIDs for ns profiling\n");
		return 1;
	}

	struct listolists *lolfirst = nil;
	struct listolists *lolcurrent=nil;
	struct listolists *lolnew=nil;
	
	lolfirst=(struct listolists *) malloc (sizeof (struct listolists));

	lolfirst->nsof=atoi(argv[1]);
	lolfirst->targlist = makenslist(argv[1]);
	lolfirst->next=(struct listolists *) malloc (sizeof (struct listolists));
	lolcurrent=lolfirst->next;

	for (int i=2; i<argc; i++){
		lolcurrent->nsof=atoi(argv[i]);
		lolcurrent->targlist=makenslist(argv[i]);
		lolcurrent->next=(struct listolists *) malloc (sizeof(struct listolists));
		lolcurrent=lolcurrent->next;
	}

	lolcurrent->next=nil;
	lolcurrent=lolfirst;
	while (lolcurrent->next !=nil){
		while (lolcurrent->targlist.current==nil)
			if (lolcurrent->next !=nil)
				lolcurrent=lolcurrent->next;
			else goto theend;
		print("process %d\n\n", lolcurrent->nsof);
		while (lolcurrent->targlist.current->next !=nil){
/*			print("%s\n", lolcurrent->targlist.current->fulline); */
			for (int j=0; j<4; j++){
				print("%25s", lolcurrent->targlist.current->tokens[j]);
			}
			print("\n");
			lolcurrent->targlist.current=lolcurrent->targlist.current->next;
		}
		lolcurrent=lolcurrent->next;
	}

theend:
	return 0;
}


struct nslist makenslist(char *targns){
	Biobuf nsbuf;
	char buf[1024];
	char *line = nil;
	int indcounter = 0;
	struct nsline *first = nil;
	struct nsline *current = nil;
	struct nsline *new = nil;
	int nsfd;

	sprint(buf, "/proc/%s/ns", targns);

	if ((nsfd = open(buf, OREAD)) == -1){
		print("cant open process %s\n", targns);
		struct nslist returnstruct = nil;
		return returnstruct;
	}
	Binit(&nsbuf, nsfd, OREAD);

	first = (struct nsline *) malloc(sizeof(struct nsline));
	line = Brdstr(&nsbuf, '\n', 1);
	first->fulline=(char *) malloc((sizeof(char))*strlen(line)+1);
	strcpy(first->fulline, line);
	tokenize(line, first->tokens, 5);
		if((*(first->tokens[1]) != '-') && (*(first->tokens[0]) != 'c')){
			first->tokens[3]=strdup(first->tokens[2]);
			first->tokens[2]=strdup(first->tokens[1]);
			first->tokens[1]=nil;
		}
	first->next = (struct nsline *) malloc(sizeof(struct nsline));
	current = first->next;

	while((line = Brdstr(&nsbuf, '\n', 1)) != nil) { 
		current->fulline = (char *) malloc((sizeof(char)) * strlen(line) + 1);
		strcpy(current->fulline, line);
		tokenize(line, current->tokens, 5); 
		if((*(current->tokens[1]) != '-') && (*(current->tokens[0]) != 'c')){
			current->tokens[3]=strdup(current->tokens[2]);
			current->tokens[2]=strdup(current->tokens[1]);
			current->tokens[1]=nil;
		}
		new = (struct nsline *) malloc(sizeof(struct nsline));
		current->next=new;
		current=new;
		indcounter++;
	} 
	
	current->next=nil;
	current=first;

	Bterm(&nsbuf);
	struct nslist returnstruct;
	returnstruct.first=first;
	returnstruct.current=current;
	returnstruct.new=new;
	return returnstruct;
}

