#include "debug.h"
#include "ocdb.h"
#include "okapi.h"
#include "common.h"

#include "config_user_key.h"

#include <string>
#include <fstream>
#include <sqlite3.h>
#include <unistd.h>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

int main(int argc, char** argv) {
	std::string Dump_path;
	bool update = 0;
	Service service = none;

	int o;
	while ((o = getopt(argc, argv, "pdui:cD:h?")) != -1)
		switch (o) {
			case 'D':
				try {
					if (std::stoi(optarg) > 0) {
						Debug::set_debug_level(std::stoi(optarg));
					}
				}
				catch (...) {
					std::cout << "Option \"-d\" requires a valid number as an argument\n";
					std::exit(EXIT_FAILURE);
				}
				break;
			case 'i':
				Dump_path = optarg;
				if (!Dump_path.ends_with('/'))
					Dump_path.push_back('/');
				break;
			case 'c':
				update = 1;
				break;
			case 'd':
				if (service != none) {
					std::cout << "Options \"-d\", \"-p\", \"-u\" are mutually exclusive.\n";
					std::exit(EXIT_FAILURE);
				}
				service = ocde;
				break;
			case 'p':
				if (service != none) {
					std::cout << "Options \"-d\", \"-p\", \"-u\" are mutually exclusive.\n";
					std::exit(EXIT_FAILURE);
				}
				service = ocpl;
				break;
			case 'u':
				if (service != none) {
					std::cout << "Options \"-d\", \"-p\", \"-u\" are mutually exclusive.\n";
					std::exit(EXIT_FAILURE);
				}
				service = ocus;
				break;
			case 'h':
			case '?':
			default:
				std::cout << "Usage: geodb [-i path] [-uh]\n";
				std::cout << "Manage local Opencaching database.\n\n";
				std::cout << "\t-i folder\tinitialize database from dump located in given folder\n";
				std::cout << "\t-c\tupdate database with changelogs grabbed via OKAPI\n";
				std::cout << "\t-h\tdisplay this help screen\n";
				std::cout << "\t-p\t\tuse opencaching.pl\n";
				std::cout << "\t-d\t\tuse opencaching.de\n";
				std::cout << "\t-u\t\tuse opencaching.us\n";

				std::exit(EXIT_FAILURE);
		}

	if (service == none) {
		std::cout << "You need to specify one of the options \"-d\", \"-p\", \"-u\".\n";
		std::exit(EXIT_FAILURE);
	}

	OCdb db(service);
	if (!Dump_path.empty())
		db.init(Dump_path);

	if (update) {
		Okapi OK(service);
		db.update(OK);
	}
	Debug(2) << "Database now at revision: " << db.get_revision();
}
