#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "vfs.h"

void  vfs_add(struct vfs *root, const char *path, void *data) {
	if (root->link && (path[0] == '/' || path[0] == '\0')) {
		vfs_add(root->link, path, data);
	}

	if (path[0]) {
		if (!root->next[path[0]]) {
			root->next[path[0]] = calloc(sizeof(struct vfs), 1);
			root->refc++;
		}
		vfs_add(root->next[path[0]], &path[1], data);
	}
	else {
		root->data = data;
	}
}

struct vfs *vfs_get(struct vfs *root, const char *path) {
	if (root->link && (path[0] == '/' || path[0] == '\0')) {
		return vfs_get(root->link, path);
	}

	if (path[0]) {
		if (!root->next[path[0]]) return NULL;
		else return vfs_get(root->next[path[0]], &path[1]);
	}
	else {
		return root;
	}
}

void  vfs_lnk(struct vfs *root, const char *path, struct vfs *link) {
	if (root->link && (path[0] == '/' || path[0] == '\0')) {
		vfs_lnk(root->link, path, link);
	}

	if (path[0]) {
		if (!root->next[path[0]]) {
			root->next[path[0]] = calloc(sizeof(struct vfs), 1);
			root->refc++;
		}
		vfs_lnk(root->next[path[0]], &path[1], link);
	}
	else {
		root->link = link;
	}
}

int vfs_rem(struct vfs *root, const char *path) {
	int f;

	if (root->link && (path[0] == '/' || path[0] == '\0')) {
		f = vfs_rem(root->link, path);
		if (f) root->link = NULL;
		return 0;
	}

	if (path[0]) {
		if (!root->next[path[0]]) return 0;
		else {
			f = vfs_rem(root->next[path[0]], &path[1]);
			if (f) {
				free(root->next[path[0]]);
				root->next[path[0]] = NULL;
				root->refc--;
			}
			if (!(root->refc || root->data)) {
				return 1;
			}
		}
	}
	else {
		return 1;
	}
	
	return 0;
}

struct vfs *vfs_root;

int main() {
	char buffer[2][100];
	struct vfs *found;

	vfs_root = calloc(sizeof(struct vfs), 1);

	while (1) {
		printf(": ");
		scanf("%s", buffer[0]);
		
		switch (buffer[0][0]) {
		case 'a':
			scanf("%s %s", buffer[0], buffer[1]);
			vfs_add(vfs_root, buffer[0], strcpy(malloc(strlen(buffer[1]) + 1), buffer[1]));
			break;
		case 'g': case 'f':
			scanf("%s", buffer[0]);
			found = vfs_get(vfs_root, buffer[0]);
			printf("> %s\n", (found) ? found->data : "NOT FOUND");
			break;
		case 'l':
			scanf("%s %s", buffer[0], buffer[1]);
			vfs_lnk(vfs_root, buffer[0], vfs_get(vfs_root, buffer[1]));
			break;
		case 'r':
			scanf("%s", buffer[0]);
			vfs_rem(vfs_root, buffer[0]);
			break;
		case 'q':
			return 0;
		}
	}

	return 0;
}