/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#include "util.h"

#define eprintf(...)  enprintf(2, __VA_ARGS__)
#define estrdup(...)  enstrdup(2, __VA_ARGS__)
#define ecalloc(...)  encalloc(2, __VA_ARGS__)
#define efshut(...)   enfshut(2, __VA_ARGS__)

#define WHITE  0
#define GREY   1
#define BLACK  2

struct vertex;

struct edge {
	struct vertex *to;
	struct edge *next;
};

struct vertex {
	char *name;
	struct vertex *next;
	struct edge edges;
	size_t in_edges;
	int colour;
};

static struct vertex graph;

static void
find_vertex(const char *name, struct vertex **it, struct vertex **prev)
{
	for (*prev = &graph; (*it = (*prev)->next); *prev = *it) {
		int cmp = strcmp(name, (*it)->name);
		if (cmp > 0)
			continue;
		if (cmp < 0)
			*it = 0;
		return;
	}
}

static void
find_edge(struct vertex* from, const char *to, struct edge **it, struct edge **prev)
{
	for (*prev = &(from->edges); (*it = (*prev)->next); *prev = *it) {
		int cmp = strcmp(to, (*it)->to->name);
		if (cmp > 0)
			continue;
		if (cmp < 0)
			*it = 0;
		return;
	}
}

static struct vertex *
add_vertex(char *name)
{
	struct vertex *vertex;
	struct vertex *prev;

	find_vertex(name, &vertex, &prev);
	if (vertex)
		return vertex;

	vertex = ecalloc(1, sizeof(*vertex));
	vertex->name = name;
	vertex->next = prev->next;
	prev->next = vertex;

	return vertex;
}

static struct edge *
add_edge(struct vertex* from, struct vertex* to)
{
	struct edge *edge;
	struct edge *prev;

	find_edge(from, to->name, &edge, &prev);
	if (edge)
		return edge;

	edge = ecalloc(1, sizeof(*edge));
	edge->to = to;
	edge->next = prev->next;
	prev->next = edge;
	to->in_edges += 1;

	return edge;
}

static void
load_graph(FILE *fp)
{
#define SKIP(VAR, START, FUNC)  for (VAR = START; FUNC(*VAR) && *VAR; VAR++)
#define TOKEN_END(P)            do { if (*P) *P++ = 0; else P = 0; } while (0)

	char *line = 0;
	size_t size = 0;
	ssize_t len;
	char *p;
	char *name;
	struct vertex *from = 0;

	while ((len = getline(&line, &size, fp)) != -1) {
		if (len && line[len - 1] == '\n')
			line[len - 1] = 0;
		for (p = line; p;) {
			SKIP(name, p, isspace);
			if (!*name)
				break;
			SKIP(p, name, !isspace);
			TOKEN_END(p);
			if (!from) {
				from = add_vertex(estrdup(name));
			} else if (strcmp(from->name, name)) {
				add_edge(from, add_vertex(estrdup(name)));
				from = 0;
			} else {
				from = 0;
			}
		}
	}

	free(line);

	if (from)
		eprintf("odd number of tokens in input, did you intended to use -l?\n");
}

static int
sort_graph_visit(struct vertex *u)
{
	struct edge *e = &(u->edges);
	struct vertex *v;
	int r = 0;
	u->colour = GREY;
	printf("%s\n", u->name);
	while ((e = e->next)) {
		v = e->to;
		if (v->colour == WHITE) {
			v->in_edges -= 1;
			if (v->in_edges == 0)
				r |= sort_graph_visit(v);
		} else if (v->colour == GREY) {
			r = 1;
			fprintf(stderr, "%s: loop detected between %s and %s\n",
			        argv0, u->name, v->name);
		}
	}
	u->colour = BLACK;
	return r;
}

static int
sort_graph(void)
{
	struct vertex *u, *prev;
	int r = 0;
	size_t in_edges;
	for (in_edges = 0; graph.next; in_edges++) {
		for (prev = &graph; (u = prev->next); prev = u) {
			if (u->colour != WHITE)
				goto unlist;
			if (u->in_edges > in_edges)
				continue;
			r |= sort_graph_visit(u);
		unlist:
			prev->next = u->next;
			u = prev;
		}
	}
	return r;
}

static void
usage(void)
{
	eprintf("usage: %s [file]\n", argv0);
}

int
main(int argc, char *argv[])
{
	FILE *fp = stdin;
	const char *fn = "<stdin>";
	int ret = 0;

	ARGBEGIN {
	default:
		usage();
	} ARGEND;

	if (argc > 1)
		usage();
	if (argc && strcmp(*argv, "-"))
		if (!(fp = fopen(fn = *argv, "r")))
			eprintf("fopen %s:", *argv);

	memset(&graph, 0, sizeof(graph));
	load_graph(fp);
	efshut(fp, fn);

	ret = sort_graph();

	if (fshut(stdout, "<stdout>") | fshut(stderr, "<stderr>"))
		ret = 2;

	return ret;
}
