/*
 * 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/.
 */

#undef NDEBUG

#include <map>
#include <ox/model/model.hpp>
#include <ox/std/std.hpp>

struct TestType {
	static constexpr auto TypeName = "net.drinkingtea.model.test.TestType";
	static constexpr auto TypeVersion = 1;
};

OX_MODEL_BEGIN(TestType)
OX_MODEL_END()

struct TestType2 {
};

template<typename Str = ox::StringView>
constexpr auto getModelTypeName(TestType2*) noexcept {
	return "net.drinkingtea.model.test.TestType2";
}

constexpr auto getModelTypeVersion(TestType2*) noexcept {
	return 2;
}

std::map<ox::StringView, ox::Error(*)()> tests = {
	{
		{
			"ModelValue",
			[] {
				ox::ModelValue v;
				OX_RETURN_ERROR(v.setType<int32_t>());
				//v.m_type = ox::ModelValue::getType<int32_t>();
				if (v.type() != ox::ModelValue::Type::SignedInteger32) {
					return ox::Error(1, "type is wrong");
				}
				OX_RETURN_ERROR(v.set<int32_t>(5));
				return ox::Error{};
			}
		},

		{
			"getModelTypeName",
			[] {
				oxAssert(ox::getModelTypeName<TestType>() == TestType::TypeName, "getModelTypeName call failed");
				oxAssert(ox::getModelTypeName<TestType2>() == ox::StringView("net.drinkingtea.model.test.TestType2"), "getModelTypeName call failed");
				return ox::Error{};
			}
		},

		{
			"getModelTypeVersion",
			[] {
				oxAssert(ox::getModelTypeVersion<TestType>() == TestType::TypeVersion, "getModelTypeVersion call failed");
				oxAssert(ox::getModelTypeVersion<TestType2>() == 2, "getModelTypeVersion call failed");
				return ox::Error{};
			}
		},
	}
};

int main(int argc, const char **args) {
	if (argc < 2) {
		oxError("Must specify test to run");
	}
	auto const testName = args[1];
	auto const func = tests.find(testName);
	if (func != tests.end()) {
		oxAssert(func->second(), "Test returned Error");
		return 0;
	}
	return -1;
}
