#include "skip.h"
#include "skunkworks.h"
#include "str.h"

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

#define _AMD64_
#define WIN32_LEAN_AND_MEAN
#include <fileapi.h>
#include <minwinbase.h>
#include <windows.h>

static const char *usage = "Usage:\n\
skip x file.skip -- extracts file.skip into a directory called file\n\
skip c dir       -- compresses contents of dir into dir.skip\n";

static struct sw_skip *skip;

void usage_and_exit() {
	printf("%s", usage);
	exit(0);
}

bool file_exists(char *dir) {
	DWORD attrib = GetFileAttributes(dir);

	return attrib != INVALID_FILE_ATTRIBUTES;
}

bool is_dir(char *dir) {
	DWORD attrib = GetFileAttributes(dir);

	return attrib != INVALID_FILE_ATTRIBUTES &&
	       attrib == FILE_ATTRIBUTE_DIRECTORY;
}

bool has_skip_ext(char *file) {
	i32 len;

	len = strlen(file);
	file += len - 5;

	return strcmp(file, ".skip") == 0;
}

char *remove_skip_ext(char *file) {
	char *str;
	i32 len;

	len = strlen(file);

	str = malloc(len - 4);
	memcpy(str, file, len - 5);
	str[len - 5] = 0;
	return str;
}

char *add_skip_ext(char *file) {
	char *str;
	i32 len;

	len = strlen(file);

	str = malloc(len + 6);
	memcpy(str, file, len);
	memcpy(str + len, ".skip", 5);
	str[len + 5] = 0;

	return str;
}

void crawl(char *dst, char *part_path) {
	WIN32_FIND_DATA data;
	HANDLE find;

	if(is_dir(dst)) {
		char *dir;
		char *path;
		char *new_part_path;

		dir = sw_str_concat(dst, "/*.*");
		find = FindFirstFile(dir, &data);
		do {
			if(strcmp(data.cFileName, ".") != 0 &&
			   strcmp(data.cFileName, "..") != 0) {
				path = sw_str_concat3(dst, "/", data.cFileName);
				if(part_path) {
					new_part_path =
					    sw_str_concat3(part_path, "/", data.cFileName);
				} else {
					new_part_path = sw_str_dup(data.cFileName);
				}
				crawl(path, new_part_path);
				free(path);
				free(new_part_path);
			}
		} while(FindNextFile(find, &data));
		free(dir);
	} else {
		sw_skip_add_file(skip, part_path, dst);
	}
}

int main(int argc, char *argv[]) {
	printf("Skip v0.0\n");
	if(argc < 3) {
		usage_and_exit();
	}

	if(strcmp(argv[1], "x") == 0) {
		/* TODO: implement */
		sw_error("extracting not yet implemented");
		/*
		char *dst;

		dst = remove_skip_ext(argv[2]);
		skip = sw_skip_load(argv[2]);

		if(file_exists(dst)) {
		    sw_error("destination %s already exists", dst);
		}

		for(i = 0; i < skip->file_count; ++i) {
		}
		*/
	} else if(strcmp(argv[1], "c") == 0) {
		char *filename;

		skip = sw_skip_create();
		if(!is_dir(argv[2])) {
			sw_error("argument not a directory");
		}
		crawl(argv[2], 0);
		filename = sw_str_concat(argv[2], ".skip");
		sw_skip_save(skip, filename);
		printf("%s created\n", filename);
		free(filename);
	} else if(strcmp(argv[1], "ca") == 0) {
		skip = sw_skip_create();
		if(!is_dir(argv[2])) {
			sw_error("argument not a directory");
		}
		crawl(argv[2], 0);
		sw_skip_attach(skip, argv[3]);
		printf("skip data attached to %s\n", argv[3]);
	} else if(strcmp(argv[1], "ca1") == 0) {
		skip = sw_skip_create();
		if(!is_dir(argv[2])) {
			sw_error("argument not a directory");
		}
		crawl(argv[2], 0);
		sw_skip_dettach(argv[3]);
		sw_skip_attach(skip, argv[3]);
		printf("skip data attached to %s\n", argv[3]);
	} else {
		usage_and_exit();
	}

	return 0;
}
