use dirs;
use path;
use format::ini;
use os;
use fs;
use strings;
use io;
use fmt;

type config = struct {
	tasksdir: str,
	context: str,
	tags: []str,
	debug: bool,
};

type cerror = !(fs::error | path::error | ini::error);

fn readconfig() (config | cerror) = {
	const c = dirs::config("hatask");
	const buf = path::init(c, "config.ini")?;
	const cpath = path::string(&buf);
	const f = os::open(cpath)?;
	defer io::close(f)!;
	const sc = ini::scan(f);
	const c = config {
		tasksdir = strings::dup("tasks"),
		context = strings::dup("*"),
		tags = [],
		debug = false,
	};
	for (const en => ini::next(&sc)?) {
		switch (en.1) {
		case "tasksdir" =>
			c.tasksdir = strings::dup(strings::trim(en.2));
		case "context" =>
			c.context = strings::dup(strings::trim(en.2));
		case "tags" =>
			c.tags = strings::dupall(strings::split(strings::trim(en.2), ","));
		case "debug" =>
			c.debug = en.2 == "true";
		case =>
			void;
		};
	};
	return c;
};

fn cfinish(cfg: *config) void = {
	free(cfg.tasksdir);
	free(cfg.context);
	strings::freeall(cfg.tags);
};

fn strcerror(e: cerror) str = {
	return match (e) {
	case let e: fs::error =>
		yield fs::strerror(e);
	case let e: path::error =>
		yield path::strerror(e);
	case let e: ini::error =>
		yield ini::strerror(e);
	case =>
		abort();
	};
};

fn printconfig(cfg: config) void = {
	fmt::errorfln("tasksdir: {}", cfg.tasksdir)!;
	fmt::errorfln("context: {}", cfg.context)!;
	const stags = strings::join(",", cfg.tags...);
	defer free(stags);
	fmt::errorfln("tags: {}", stags)!;
};
