#include "base/exception.hpp"
#include "base/objectlock.hpp"
#include "base/utility.hpp"
#include "base/convert.hpp"
#include "base/debug.hpp"
#include "base/dependencygraph.hpp"
#include "base/logger.hpp"
#include "base/function.hpp"
#include "base/configobject.hpp"
#include "base/configtype.hpp"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-variable"
namespace icinga
{

TypeImpl<IcingaApplication>::TypeImpl()
{ }

TypeImpl<IcingaApplication>::~TypeImpl()
{ }

String TypeImpl<IcingaApplication>::GetName() const
{
	return "IcingaApplication";
}

int TypeImpl<IcingaApplication>::GetAttributes() const
{
	return 0;
}

Type::Ptr TypeImpl<IcingaApplication>::GetBaseType() const
{
	return Application::TypeInstance;
}

int TypeImpl<IcingaApplication>::GetFieldId(const String& name) const
{
	int offset = Application::TypeInstance->GetFieldCount();

	switch (static_cast<int>(Utility::SDBM(name, 8))) {
		case -1766450871:
			if (name == "enable_event_handlers")
				return offset + 3;

			break;
		case -1766450870:
			if (name == "enable_flapping")
				return offset + 4;

			break;
		case -1766450868:
			if (name == "enable_host_checks")
				return offset + 5;

			break;
		case -1766450862:
			if (name == "enable_notifications")
				return offset + 2;

			break;
		case -1766450860:
			if (name == "enable_perfdata")
				return offset + 7;

			break;
		case -1766450857:
			if (name == "enable_service_checks")
				return offset + 6;

			break;
		case -1571146644:
			if (name == "vars")
				return offset + 1;

			break;
		case 1609904056:
			if (name == "environment")
				return offset + 0;

			break;
	}

	return Application::TypeInstance->GetFieldId(name);
}

Field TypeImpl<IcingaApplication>::GetFieldInfo(int id) const
{
	int real_id = id - Application::TypeInstance->GetFieldCount();
	if (real_id < 0) { return Application::TypeInstance->GetFieldInfo(id); }
	switch (real_id) {
		case 0:
			return {0, "String", "environment", "environment", nullptr, 24642, 0};
		case 1:
			return {1, "Dictionary", "vars", "vars", nullptr, 2, 0};
		case 2:
			return {2, "Boolean", "enable_notifications", "enable_notifications", nullptr, 2, 0};
		case 3:
			return {3, "Boolean", "enable_event_handlers", "enable_event_handlers", nullptr, 2, 0};
		case 4:
			return {4, "Boolean", "enable_flapping", "enable_flapping", nullptr, 2, 0};
		case 5:
			return {5, "Boolean", "enable_host_checks", "enable_host_checks", nullptr, 2, 0};
		case 6:
			return {6, "Boolean", "enable_service_checks", "enable_service_checks", nullptr, 2, 0};
		case 7:
			return {7, "Boolean", "enable_perfdata", "enable_perfdata", nullptr, 2, 0};
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

int TypeImpl<IcingaApplication>::GetFieldCount() const
{
	return 8 + Application::TypeInstance->GetFieldCount();
}

ObjectFactory TypeImpl<IcingaApplication>::GetFactory() const
{
	return TypeHelper<IcingaApplication, false>::GetFactory();
}

int TypeImpl<IcingaApplication>::GetActivationPriority() const
{
	return -50;
}

void TypeImpl<IcingaApplication>::RegisterAttributeHandler(int fieldId, const Type::AttributeHandler& callback)
{
	int real_id = fieldId - Application::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { Application::TypeInstance->RegisterAttributeHandler(fieldId, callback); return; }
	switch (real_id) {
		case 0:
			ObjectImpl<IcingaApplication>::OnEnvironmentChanged.connect(callback);
			break;
		case 1:
			ObjectImpl<IcingaApplication>::OnVarsChanged.connect(callback);
			break;
		case 2:
			ObjectImpl<IcingaApplication>::OnEnableNotificationsChanged.connect(callback);
			break;
		case 3:
			ObjectImpl<IcingaApplication>::OnEnableEventHandlersChanged.connect(callback);
			break;
		case 4:
			ObjectImpl<IcingaApplication>::OnEnableFlappingChanged.connect(callback);
			break;
		case 5:
			ObjectImpl<IcingaApplication>::OnEnableHostChecksChanged.connect(callback);
			break;
		case 6:
			ObjectImpl<IcingaApplication>::OnEnableServiceChecksChanged.connect(callback);
			break;
		case 7:
			ObjectImpl<IcingaApplication>::OnEnablePerfdataChanged.connect(callback);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<IcingaApplication>::Validate(int types, const ValidationUtils& utils)
{
	Application::Validate(types, utils);

	if (2 & types)
		ValidateEnvironment(Lazy<String>([this]() { return GetEnvironment(); }), utils);
	if (2 & types)
		ValidateVars(Lazy<Dictionary::Ptr>([this]() { return GetVars(); }), utils);
	if (2 & types)
		ValidateEnableNotifications(Lazy<bool>([this]() { return GetEnableNotifications(); }), utils);
	if (2 & types)
		ValidateEnableEventHandlers(Lazy<bool>([this]() { return GetEnableEventHandlers(); }), utils);
	if (2 & types)
		ValidateEnableFlapping(Lazy<bool>([this]() { return GetEnableFlapping(); }), utils);
	if (2 & types)
		ValidateEnableHostChecks(Lazy<bool>([this]() { return GetEnableHostChecks(); }), utils);
	if (2 & types)
		ValidateEnableServiceChecks(Lazy<bool>([this]() { return GetEnableServiceChecks(); }), utils);
	if (2 & types)
		ValidateEnablePerfdata(Lazy<bool>([this]() { return GetEnablePerfdata(); }), utils);
}

void ObjectImpl<IcingaApplication>::SimpleValidateEnvironment(const Lazy<String>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<IcingaApplication>::SimpleValidateVars(const Lazy<Dictionary::Ptr>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<IcingaApplication>::SimpleValidateEnableNotifications(const Lazy<bool>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<IcingaApplication>::SimpleValidateEnableEventHandlers(const Lazy<bool>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<IcingaApplication>::SimpleValidateEnableFlapping(const Lazy<bool>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<IcingaApplication>::SimpleValidateEnableHostChecks(const Lazy<bool>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<IcingaApplication>::SimpleValidateEnableServiceChecks(const Lazy<bool>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<IcingaApplication>::SimpleValidateEnablePerfdata(const Lazy<bool>& value, const ValidationUtils& utils)
{
}

ObjectImpl<IcingaApplication>::ObjectImpl()
{
	SetVars(GetDefaultVars(), true);
	SetEnableNotifications(GetDefaultEnableNotifications(), true);
	SetEnableEventHandlers(GetDefaultEnableEventHandlers(), true);
	SetEnableFlapping(GetDefaultEnableFlapping(), true);
	SetEnableHostChecks(GetDefaultEnableHostChecks(), true);
	SetEnableServiceChecks(GetDefaultEnableServiceChecks(), true);
	SetEnablePerfdata(GetDefaultEnablePerfdata(), true);
}

ObjectImpl<IcingaApplication>::~ObjectImpl()
{ }

void ObjectImpl<IcingaApplication>::SetField(int id, const Value& value, bool suppress_events, const Value& cookie)
{
	int real_id = id - Application::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { Application::SetField(id, value, suppress_events, cookie); return; }
	switch (real_id) {
		case 0:
			SetEnvironment(value, suppress_events, cookie);
			break;
		case 1:
			SetVars(value, suppress_events, cookie);
			break;
		case 2:
			SetEnableNotifications(value, suppress_events, cookie);
			break;
		case 3:
			SetEnableEventHandlers(value, suppress_events, cookie);
			break;
		case 4:
			SetEnableFlapping(value, suppress_events, cookie);
			break;
		case 5:
			SetEnableHostChecks(value, suppress_events, cookie);
			break;
		case 6:
			SetEnableServiceChecks(value, suppress_events, cookie);
			break;
		case 7:
			SetEnablePerfdata(value, suppress_events, cookie);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

Value ObjectImpl<IcingaApplication>::GetField(int id) const
{
	int real_id = id - Application::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { return Application::GetField(id); }
	switch (real_id) {
		case 0:
			return GetEnvironment();
		case 1:
			return GetVars();
		case 2:
			return GetEnableNotifications();
		case 3:
			return GetEnableEventHandlers();
		case 4:
			return GetEnableFlapping();
		case 5:
			return GetEnableHostChecks();
		case 6:
			return GetEnableServiceChecks();
		case 7:
			return GetEnablePerfdata();
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<IcingaApplication>::ValidateField(int id, const Lazy<Value>& lvalue, const ValidationUtils& utils)
{
	int real_id = id - Application::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { Application::ValidateField(id, lvalue, utils); return; }
	switch (real_id) {
		case 0:
			ValidateEnvironment(lvalue, utils);
			break;
		case 1:
			ValidateVars(lvalue, utils);
			break;
		case 2:
			ValidateEnableNotifications(lvalue, utils);
			break;
		case 3:
			ValidateEnableEventHandlers(lvalue, utils);
			break;
		case 4:
			ValidateEnableFlapping(lvalue, utils);
			break;
		case 5:
			ValidateEnableHostChecks(lvalue, utils);
			break;
		case 6:
			ValidateEnableServiceChecks(lvalue, utils);
			break;
		case 7:
			ValidateEnablePerfdata(lvalue, utils);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<IcingaApplication>::NotifyField(int id, const Value& cookie)
{
	int real_id = id - Application::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { Application::NotifyField(id, cookie); return; }
	switch (real_id) {
		case 0:
			NotifyEnvironment(cookie);
			break;
		case 1:
			NotifyVars(cookie);
			break;
		case 2:
			NotifyEnableNotifications(cookie);
			break;
		case 3:
			NotifyEnableEventHandlers(cookie);
			break;
		case 4:
			NotifyEnableFlapping(cookie);
			break;
		case 5:
			NotifyEnableHostChecks(cookie);
			break;
		case 6:
			NotifyEnableServiceChecks(cookie);
			break;
		case 7:
			NotifyEnablePerfdata(cookie);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

Object::Ptr ObjectImpl<IcingaApplication>::NavigateField(int id) const
{
	int real_id = id - Application::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { return Application::NavigateField(id); }
	throw std::runtime_error("Invalid field ID.");
}

Dictionary::Ptr ObjectImpl<IcingaApplication>::GetVars() const
{
	return m_Vars.load();
}

bool ObjectImpl<IcingaApplication>::GetEnableNotifications() const
{
	return m_EnableNotifications.load();
}

bool ObjectImpl<IcingaApplication>::GetEnableEventHandlers() const
{
	return m_EnableEventHandlers.load();
}

bool ObjectImpl<IcingaApplication>::GetEnableFlapping() const
{
	return m_EnableFlapping.load();
}

bool ObjectImpl<IcingaApplication>::GetEnableHostChecks() const
{
	return m_EnableHostChecks.load();
}

bool ObjectImpl<IcingaApplication>::GetEnableServiceChecks() const
{
	return m_EnableServiceChecks.load();
}

bool ObjectImpl<IcingaApplication>::GetEnablePerfdata() const
{
	return m_EnablePerfdata.load();
}

void ObjectImpl<IcingaApplication>::SetVars(const Dictionary::Ptr& value, bool suppress_events, const Value& cookie)
{
	m_Vars.store(value);
	if (!suppress_events) {
		NotifyVars(cookie);
	}

}

void ObjectImpl<IcingaApplication>::SetEnableNotifications(bool value, bool suppress_events, const Value& cookie)
{
	m_EnableNotifications.store(value);
	if (!suppress_events) {
		NotifyEnableNotifications(cookie);
	}

}

void ObjectImpl<IcingaApplication>::SetEnableEventHandlers(bool value, bool suppress_events, const Value& cookie)
{
	m_EnableEventHandlers.store(value);
	if (!suppress_events) {
		NotifyEnableEventHandlers(cookie);
	}

}

void ObjectImpl<IcingaApplication>::SetEnableFlapping(bool value, bool suppress_events, const Value& cookie)
{
	m_EnableFlapping.store(value);
	if (!suppress_events) {
		NotifyEnableFlapping(cookie);
	}

}

void ObjectImpl<IcingaApplication>::SetEnableHostChecks(bool value, bool suppress_events, const Value& cookie)
{
	m_EnableHostChecks.store(value);
	if (!suppress_events) {
		NotifyEnableHostChecks(cookie);
	}

}

void ObjectImpl<IcingaApplication>::SetEnableServiceChecks(bool value, bool suppress_events, const Value& cookie)
{
	m_EnableServiceChecks.store(value);
	if (!suppress_events) {
		NotifyEnableServiceChecks(cookie);
	}

}

void ObjectImpl<IcingaApplication>::SetEnablePerfdata(bool value, bool suppress_events, const Value& cookie)
{
	m_EnablePerfdata.store(value);
	if (!suppress_events) {
		NotifyEnablePerfdata(cookie);
	}

}

void ObjectImpl<IcingaApplication>::NotifyEnvironment(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnEnvironmentChanged(static_cast<IcingaApplication *>(this), cookie);
}

void ObjectImpl<IcingaApplication>::NotifyVars(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnVarsChanged(static_cast<IcingaApplication *>(this), cookie);
}

void ObjectImpl<IcingaApplication>::NotifyEnableNotifications(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnEnableNotificationsChanged(static_cast<IcingaApplication *>(this), cookie);
}

void ObjectImpl<IcingaApplication>::NotifyEnableEventHandlers(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnEnableEventHandlersChanged(static_cast<IcingaApplication *>(this), cookie);
}

void ObjectImpl<IcingaApplication>::NotifyEnableFlapping(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnEnableFlappingChanged(static_cast<IcingaApplication *>(this), cookie);
}

void ObjectImpl<IcingaApplication>::NotifyEnableHostChecks(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnEnableHostChecksChanged(static_cast<IcingaApplication *>(this), cookie);
}

void ObjectImpl<IcingaApplication>::NotifyEnableServiceChecks(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnEnableServiceChecksChanged(static_cast<IcingaApplication *>(this), cookie);
}

void ObjectImpl<IcingaApplication>::NotifyEnablePerfdata(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnEnablePerfdataChanged(static_cast<IcingaApplication *>(this), cookie);
}

String ObjectImpl<IcingaApplication>::GetDefaultEnvironment() const
{
	 return Application::GetAppEnvironment(); 
}

Dictionary::Ptr ObjectImpl<IcingaApplication>::GetDefaultVars() const
{
	return Dictionary::Ptr();
}

bool ObjectImpl<IcingaApplication>::GetDefaultEnableNotifications() const
{
	 return true; 
}

bool ObjectImpl<IcingaApplication>::GetDefaultEnableEventHandlers() const
{
	 return true; 
}

bool ObjectImpl<IcingaApplication>::GetDefaultEnableFlapping() const
{
	 return true; 
}

bool ObjectImpl<IcingaApplication>::GetDefaultEnableHostChecks() const
{
	 return true; 
}

bool ObjectImpl<IcingaApplication>::GetDefaultEnableServiceChecks() const
{
	 return true; 
}

bool ObjectImpl<IcingaApplication>::GetDefaultEnablePerfdata() const
{
	 return true; 
}


boost::signals2::signal<void (const intrusive_ptr<IcingaApplication>&, const Value&)> ObjectImpl<IcingaApplication>::OnEnvironmentChanged;


boost::signals2::signal<void (const intrusive_ptr<IcingaApplication>&, const Value&)> ObjectImpl<IcingaApplication>::OnVarsChanged;


boost::signals2::signal<void (const intrusive_ptr<IcingaApplication>&, const Value&)> ObjectImpl<IcingaApplication>::OnEnableNotificationsChanged;


boost::signals2::signal<void (const intrusive_ptr<IcingaApplication>&, const Value&)> ObjectImpl<IcingaApplication>::OnEnableEventHandlersChanged;


boost::signals2::signal<void (const intrusive_ptr<IcingaApplication>&, const Value&)> ObjectImpl<IcingaApplication>::OnEnableFlappingChanged;


boost::signals2::signal<void (const intrusive_ptr<IcingaApplication>&, const Value&)> ObjectImpl<IcingaApplication>::OnEnableHostChecksChanged;


boost::signals2::signal<void (const intrusive_ptr<IcingaApplication>&, const Value&)> ObjectImpl<IcingaApplication>::OnEnableServiceChecksChanged;


boost::signals2::signal<void (const intrusive_ptr<IcingaApplication>&, const Value&)> ObjectImpl<IcingaApplication>::OnEnablePerfdataChanged;

void ObjectImpl<IcingaApplication>::ValidateEnableEventHandlers(const Lazy<bool>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateEnableEventHandlers(lvalue, utils);
}

void ObjectImpl<IcingaApplication>::ValidateEnableFlapping(const Lazy<bool>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateEnableFlapping(lvalue, utils);
}

void ObjectImpl<IcingaApplication>::ValidateEnableHostChecks(const Lazy<bool>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateEnableHostChecks(lvalue, utils);
}

void ObjectImpl<IcingaApplication>::ValidateEnableNotifications(const Lazy<bool>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateEnableNotifications(lvalue, utils);
}

void ObjectImpl<IcingaApplication>::ValidateEnablePerfdata(const Lazy<bool>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateEnablePerfdata(lvalue, utils);
}

void ObjectImpl<IcingaApplication>::ValidateEnableServiceChecks(const Lazy<bool>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateEnableServiceChecks(lvalue, utils);
}

void ObjectImpl<IcingaApplication>::ValidateEnvironment(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateEnvironment(lvalue, utils);
}

void ObjectImpl<IcingaApplication>::ValidateVars(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateVars(lvalue, utils);
}

}
#pragma GCC diagnostic pop
