/*
 * Copyright 2015 - 2025 gary@drinkingtea.net
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

#include <ox/std/string.hpp>
#include <ox/clargs/clargs.hpp>

namespace ox {

ClArgs::ClArgs(int argc, const char **args) noexcept: ClArgs({args, static_cast<size_t>(argc)}) {}

ClArgs::ClArgs(ox::SpanView<const char*> args) noexcept {
	for (auto i = 0u; i < args.size(); ++i) {
		auto arg = StringView{args[i]};
		if (arg[0] == '-') {
			while (arg[0] == '-' && arg.size()) {
				arg = substr(arg, 1);
			}
			m_bools[arg] = true;
			// parse additional arguments
			if (i < args.size() && args[i + 1]) {
				auto const val = StringView{args[i + 1]};
				if (val.size() && val[0] != '-') {
					if (val == "false") {
						m_bools[arg] = false;
					}
					m_strings[arg] = val;
					if (auto r = ox::strToInt(val); r.error == 0) {
						m_ints[arg] = r.value;
					}
					++i;
				}
			}
		}
	}
}

bool ClArgs::getBool(ox::StringViewCR arg, bool defaultValue) const noexcept {
	auto const [value, err] = m_ints.at(arg);
	return !err ? *value : defaultValue;
}

String ClArgs::getString(ox::StringViewCR arg, ox::StringView defaultValue) const noexcept {
	auto const [value, err] = m_strings.at(arg);
	return !err ? ox::String(*value) : ox::String(defaultValue);
}

int ClArgs::getInt(ox::StringViewCR arg, int defaultValue) const noexcept {
	auto const [value, err] = m_ints.at(arg);
	return !err ? *value : defaultValue;
}

Result<bool> ClArgs::getBool(ox::StringViewCR arg) const noexcept {
	OX_REQUIRE(out, m_bools.at(arg));
	return *out;
}

Result<String> ClArgs::getString(ox::StringViewCR argName) const noexcept {
	OX_REQUIRE(out, m_strings.at(argName));
	return *out;
}

Result<int> ClArgs::getInt(ox::StringViewCR arg) const noexcept {
	OX_REQUIRE(out, m_ints.at(arg));
	return *out;
}

}
