#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"
#include "icinga/service.hpp"

namespace icinga
{

TypeImpl<Downtime>::TypeImpl()
{ }

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

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

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

Type::Ptr TypeImpl<Downtime>::GetBaseType() const
{
	return ConfigObject::TypeInstance;
}

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

	switch (static_cast<int>(Utility::SDBM(name, 7))) {
		case -1299862792:
			if (name == "triggered_by")
				return offset + 0;
			if (name == "triggers")
				return offset + 11;
			if (name == "trigger_time")
				return offset + 14;

			break;
		case -1164688629:
			if (name == "author")
				return offset + 9;

			break;
		case -1055240377:
			if (name == "entry_time")
				return offset + 18;

			break;
		case -632718091:
			if (name == "service_name")
				return offset + 10;

			break;
		case -454220870:
			if (name == "duration")
				return offset + 13;

			break;
		case -316870054:
			if (name == "was_cancelled")
				return offset + 20;

			break;
		case -312680786:
			if (name == "scheduled_by")
				return offset + 6;

			break;
		case -277067977:
			if (name == "start_time")
				return offset + 16;

			break;
		case 199661044:
			if (name == "end_time")
				return offset + 15;

			break;
		case 763854878:
			if (name == "authoritative_zone")
				return offset + 2;

			break;
		case 1074227990:
			if (name == "legacy_id")
				return offset + 12;

			break;
		case 1512946026:
			if (name == "parent")
				return offset + 5;

			break;
		case 1561195615:
			if (name == "comment")
				return offset + 8;

			break;
		case 1564203613:
			if (name == "config_owner_hash")
				return offset + 3;
			if (name == "config_owner")
				return offset + 4;

			break;
		case 1626723956:
			if (name == "fixed")
				return offset + 19;

			break;
		case 1714040586:
			if (name == "host_name")
				return offset + 7;

			break;
		case 1899612219:
			if (name == "remove_time")
				return offset + 17;

			break;
		case 1899612224:
			if (name == "removed_by")
				return offset + 1;

			break;
	}

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

Field TypeImpl<Downtime>::GetFieldInfo(int id) const
{
	int real_id = id - ConfigObject::TypeInstance->GetFieldCount();
	if (real_id < 0) { return ConfigObject::TypeInstance->GetFieldInfo(id); }
	switch (real_id) {
		case 0:
			return {0, "String", "triggered_by", "triggered_by", nullptr, 2, 0};
		case 1:
			return {1, "String", "removed_by", "removed_by", nullptr, 3073, 0};
		case 2:
			return {2, "String", "authoritative_zone", "authoritative_zone", nullptr, 2, 0};
		case 3:
			return {3, "String", "config_owner_hash", "config_owner_hash", nullptr, 2, 0};
		case 4:
			return {4, "String", "config_owner", "config_owner", nullptr, 2, 0};
		case 5:
			return {5, "String", "parent", "parent", nullptr, 2, 0};
		case 6:
			return {6, "String", "scheduled_by", "scheduled_by", nullptr, 2, 0};
		case 7:
			return {7, "String", "host_name", "host", "Host", 1794, 0};
		case 8:
			return {8, "String", "comment", "comment", nullptr, 258, 0};
		case 9:
			return {9, "String", "author", "author", nullptr, 258, 0};
		case 10:
			return {10, "String", "service_name", "service", nullptr, 1538, 0};
		case 11:
			return {11, "Array", "triggers", "triggers", nullptr, 4, 0};
		case 12:
			return {12, "Number", "legacy_id", "legacy_id", nullptr, 4, 0};
		case 13:
			return {13, "Timestamp", "duration", "duration", nullptr, 2, 0};
		case 14:
			return {14, "Timestamp", "trigger_time", "trigger_time", nullptr, 4, 0};
		case 15:
			return {15, "Timestamp", "end_time", "end_time", nullptr, 2, 0};
		case 16:
			return {16, "Timestamp", "start_time", "start_time", nullptr, 2, 0};
		case 17:
			return {17, "Timestamp", "remove_time", "remove_time", nullptr, 4, 0};
		case 18:
			return {18, "Timestamp", "entry_time", "entry_time", nullptr, 2, 0};
		case 19:
			return {19, "Boolean", "fixed", "fixed", nullptr, 2, 0};
		case 20:
			return {20, "Boolean", "was_cancelled", "was_cancelled", nullptr, 65, 0};
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

int TypeImpl<Downtime>::GetFieldCount() const
{
	return 21 + ConfigObject::TypeInstance->GetFieldCount();
}

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

const std::unordered_set<Type*>& TypeImpl<Downtime>::GetLoadDependencies() const
{
	static const auto deps ([] {
		auto typeHost (GetByName("Host").get());
		VERIFY(typeHost);
		VERIFY(ConfigObject::TypeInstance->IsAssignableFrom(typeHost));

		auto typeService (GetByName("Service").get());
		VERIFY(typeService);
		VERIFY(ConfigObject::TypeInstance->IsAssignableFrom(typeService));

		return std::unordered_set<Type*>{ typeHost, typeService, };
	}());

	return deps;
}

int TypeImpl<Downtime>::GetActivationPriority() const
{
	return -10;
}

void TypeImpl<Downtime>::RegisterAttributeHandler(int fieldId, const Type::AttributeHandler& callback)
{
	int real_id = fieldId - ConfigObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { ConfigObject::TypeInstance->RegisterAttributeHandler(fieldId, callback); return; }
	switch (real_id) {
		case 0:
			ObjectImpl<Downtime>::OnTriggeredByChanged.connect(callback);
			break;
		case 1:
			ObjectImpl<Downtime>::OnRemovedByChanged.connect(callback);
			break;
		case 2:
			ObjectImpl<Downtime>::OnAuthoritativeZoneChanged.connect(callback);
			break;
		case 3:
			ObjectImpl<Downtime>::OnConfigOwnerHashChanged.connect(callback);
			break;
		case 4:
			ObjectImpl<Downtime>::OnConfigOwnerChanged.connect(callback);
			break;
		case 5:
			ObjectImpl<Downtime>::OnParentChanged.connect(callback);
			break;
		case 6:
			ObjectImpl<Downtime>::OnScheduledByChanged.connect(callback);
			break;
		case 7:
			ObjectImpl<Downtime>::OnHostNameChanged.connect(callback);
			break;
		case 8:
			ObjectImpl<Downtime>::OnCommentChanged.connect(callback);
			break;
		case 9:
			ObjectImpl<Downtime>::OnAuthorChanged.connect(callback);
			break;
		case 10:
			ObjectImpl<Downtime>::OnServiceNameChanged.connect(callback);
			break;
		case 11:
			ObjectImpl<Downtime>::OnTriggersChanged.connect(callback);
			break;
		case 12:
			ObjectImpl<Downtime>::OnLegacyIdChanged.connect(callback);
			break;
		case 13:
			ObjectImpl<Downtime>::OnDurationChanged.connect(callback);
			break;
		case 14:
			ObjectImpl<Downtime>::OnTriggerTimeChanged.connect(callback);
			break;
		case 15:
			ObjectImpl<Downtime>::OnEndTimeChanged.connect(callback);
			break;
		case 16:
			ObjectImpl<Downtime>::OnStartTimeChanged.connect(callback);
			break;
		case 17:
			ObjectImpl<Downtime>::OnRemoveTimeChanged.connect(callback);
			break;
		case 18:
			ObjectImpl<Downtime>::OnEntryTimeChanged.connect(callback);
			break;
		case 19:
			ObjectImpl<Downtime>::OnFixedChanged.connect(callback);
			break;
		case 20:
			ObjectImpl<Downtime>::OnWasCancelledChanged.connect(callback);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

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

	if (2 & types)
		ValidateTriggeredBy(Lazy<String>([this]() { return GetTriggeredBy(); }), utils);
	if (1 & types)
		ValidateRemovedBy(Lazy<String>([this]() { return GetRemovedBy(); }), utils);
	if (2 & types)
		ValidateAuthoritativeZone(Lazy<String>([this]() { return GetAuthoritativeZone(); }), utils);
	if (2 & types)
		ValidateConfigOwnerHash(Lazy<String>([this]() { return GetConfigOwnerHash(); }), utils);
	if (2 & types)
		ValidateConfigOwner(Lazy<String>([this]() { return GetConfigOwner(); }), utils);
	if (2 & types)
		ValidateParent(Lazy<String>([this]() { return GetParent(); }), utils);
	if (2 & types)
		ValidateScheduledBy(Lazy<String>([this]() { return GetScheduledBy(); }), utils);
	if (2 & types)
		ValidateHostName(Lazy<String>([this]() { return GetHostName(); }), utils);
	if (2 & types)
		ValidateComment(Lazy<String>([this]() { return GetComment(); }), utils);
	if (2 & types)
		ValidateAuthor(Lazy<String>([this]() { return GetAuthor(); }), utils);
	if (2 & types)
		ValidateServiceName(Lazy<String>([this]() { return GetServiceName(); }), utils);
	if (4 & types)
		ValidateTriggers(Lazy<Array::Ptr>([this]() { return GetTriggers(); }), utils);
	if (4 & types)
		ValidateLegacyId(Lazy<int>([this]() { return GetLegacyId(); }), utils);
	if (2 & types)
		ValidateDuration(Lazy<Timestamp>([this]() { return GetDuration(); }), utils);
	if (4 & types)
		ValidateTriggerTime(Lazy<Timestamp>([this]() { return GetTriggerTime(); }), utils);
	if (2 & types)
		ValidateEndTime(Lazy<Timestamp>([this]() { return GetEndTime(); }), utils);
	if (2 & types)
		ValidateStartTime(Lazy<Timestamp>([this]() { return GetStartTime(); }), utils);
	if (4 & types)
		ValidateRemoveTime(Lazy<Timestamp>([this]() { return GetRemoveTime(); }), utils);
	if (2 & types)
		ValidateEntryTime(Lazy<Timestamp>([this]() { return GetEntryTime(); }), utils);
	if (2 & types)
		ValidateFixed(Lazy<bool>([this]() { return GetFixed(); }), utils);
	if (1 & types)
		ValidateWasCancelled(Lazy<bool>([this]() { return GetWasCancelled(); }), utils);
}

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

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

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

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

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

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

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

void ObjectImpl<Downtime>::SimpleValidateHostName(const Lazy<String>& value, const ValidationUtils& utils)
{
	if (value().IsEmpty())
		BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "host_name" }, "Attribute must not be empty."));

			if (!value().IsEmpty() && !utils.ValidateName("Host", value()))
				BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "host_name" }, "Object '" + value() + "' of type 'Host' does not exist."));
}

void ObjectImpl<Downtime>::SimpleValidateComment(const Lazy<String>& value, const ValidationUtils& utils)
{
	if (value().IsEmpty())
		BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "comment" }, "Attribute must not be empty."));

}

void ObjectImpl<Downtime>::SimpleValidateAuthor(const Lazy<String>& value, const ValidationUtils& utils)
{
	if (value().IsEmpty())
		BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "author" }, "Attribute must not be empty."));

}

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

void ObjectImpl<Downtime>::SimpleValidateTriggers(const Lazy<Array::Ptr>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Downtime>::SimpleValidateLegacyId(const Lazy<int>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Downtime>::SimpleValidateDuration(const Lazy<Timestamp>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Downtime>::SimpleValidateTriggerTime(const Lazy<Timestamp>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Downtime>::SimpleValidateEndTime(const Lazy<Timestamp>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Downtime>::SimpleValidateStartTime(const Lazy<Timestamp>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Downtime>::SimpleValidateRemoveTime(const Lazy<Timestamp>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Downtime>::SimpleValidateEntryTime(const Lazy<Timestamp>& value, const ValidationUtils& utils)
{
}

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

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

ObjectImpl<Downtime>::ObjectImpl()
{
	SetTriggeredBy(GetDefaultTriggeredBy(), true);
	SetRemovedBy(GetDefaultRemovedBy(), true);
	SetAuthoritativeZone(GetDefaultAuthoritativeZone(), true);
	SetConfigOwnerHash(GetDefaultConfigOwnerHash(), true);
	SetConfigOwner(GetDefaultConfigOwner(), true);
	SetParent(GetDefaultParent(), true);
	SetScheduledBy(GetDefaultScheduledBy(), true);
	SetHostName(GetDefaultHostName(), true);
	SetComment(GetDefaultComment(), true);
	SetAuthor(GetDefaultAuthor(), true);
	SetServiceName(GetDefaultServiceName(), true);
	SetTriggers(GetDefaultTriggers(), true);
	SetLegacyId(GetDefaultLegacyId(), true);
	SetDuration(GetDefaultDuration(), true);
	SetTriggerTime(GetDefaultTriggerTime(), true);
	SetEndTime(GetDefaultEndTime(), true);
	SetStartTime(GetDefaultStartTime(), true);
	SetRemoveTime(GetDefaultRemoveTime(), true);
	SetEntryTime(GetDefaultEntryTime(), true);
	SetFixed(GetDefaultFixed(), true);
	SetWasCancelled(GetDefaultWasCancelled(), true);
}

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

void ObjectImpl<Downtime>::SetField(int id, const Value& value, bool suppress_events, const Value& cookie)
{
	int real_id = id - ConfigObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { ConfigObject::SetField(id, value, suppress_events, cookie); return; }
	switch (real_id) {
		case 0:
			SetTriggeredBy(value, suppress_events, cookie);
			break;
		case 1:
			SetRemovedBy(value, suppress_events, cookie);
			break;
		case 2:
			SetAuthoritativeZone(value, suppress_events, cookie);
			break;
		case 3:
			SetConfigOwnerHash(value, suppress_events, cookie);
			break;
		case 4:
			SetConfigOwner(value, suppress_events, cookie);
			break;
		case 5:
			SetParent(value, suppress_events, cookie);
			break;
		case 6:
			SetScheduledBy(value, suppress_events, cookie);
			break;
		case 7:
			SetHostName(value, suppress_events, cookie);
			break;
		case 8:
			SetComment(value, suppress_events, cookie);
			break;
		case 9:
			SetAuthor(value, suppress_events, cookie);
			break;
		case 10:
			SetServiceName(value, suppress_events, cookie);
			break;
		case 11:
			SetTriggers(value, suppress_events, cookie);
			break;
		case 12:
			SetLegacyId(value, suppress_events, cookie);
			break;
		case 13:
			SetDuration(value, suppress_events, cookie);
			break;
		case 14:
			SetTriggerTime(value, suppress_events, cookie);
			break;
		case 15:
			SetEndTime(value, suppress_events, cookie);
			break;
		case 16:
			SetStartTime(value, suppress_events, cookie);
			break;
		case 17:
			SetRemoveTime(value, suppress_events, cookie);
			break;
		case 18:
			SetEntryTime(value, suppress_events, cookie);
			break;
		case 19:
			SetFixed(value, suppress_events, cookie);
			break;
		case 20:
			SetWasCancelled(value, suppress_events, cookie);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

Value ObjectImpl<Downtime>::GetField(int id) const
{
	int real_id = id - ConfigObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { return ConfigObject::GetField(id); }
	switch (real_id) {
		case 0:
			return GetTriggeredBy();
		case 1:
			return GetRemovedBy();
		case 2:
			return GetAuthoritativeZone();
		case 3:
			return GetConfigOwnerHash();
		case 4:
			return GetConfigOwner();
		case 5:
			return GetParent();
		case 6:
			return GetScheduledBy();
		case 7:
			return GetHostName();
		case 8:
			return GetComment();
		case 9:
			return GetAuthor();
		case 10:
			return GetServiceName();
		case 11:
			return GetTriggers();
		case 12:
			return GetLegacyId();
		case 13:
			return GetDuration();
		case 14:
			return GetTriggerTime();
		case 15:
			return GetEndTime();
		case 16:
			return GetStartTime();
		case 17:
			return GetRemoveTime();
		case 18:
			return GetEntryTime();
		case 19:
			return GetFixed();
		case 20:
			return GetWasCancelled();
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<Downtime>::ValidateField(int id, const Lazy<Value>& lvalue, const ValidationUtils& utils)
{
	int real_id = id - ConfigObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { ConfigObject::ValidateField(id, lvalue, utils); return; }
	switch (real_id) {
		case 0:
			ValidateTriggeredBy(lvalue, utils);
			break;
		case 1:
			ValidateRemovedBy(lvalue, utils);
			break;
		case 2:
			ValidateAuthoritativeZone(lvalue, utils);
			break;
		case 3:
			ValidateConfigOwnerHash(lvalue, utils);
			break;
		case 4:
			ValidateConfigOwner(lvalue, utils);
			break;
		case 5:
			ValidateParent(lvalue, utils);
			break;
		case 6:
			ValidateScheduledBy(lvalue, utils);
			break;
		case 7:
			ValidateHostName(lvalue, utils);
			break;
		case 8:
			ValidateComment(lvalue, utils);
			break;
		case 9:
			ValidateAuthor(lvalue, utils);
			break;
		case 10:
			ValidateServiceName(lvalue, utils);
			break;
		case 11:
			ValidateTriggers(lvalue, utils);
			break;
		case 12:
			ValidateLegacyId(lvalue, utils);
			break;
		case 13:
			ValidateDuration(lvalue, utils);
			break;
		case 14:
			ValidateTriggerTime(lvalue, utils);
			break;
		case 15:
			ValidateEndTime(lvalue, utils);
			break;
		case 16:
			ValidateStartTime(lvalue, utils);
			break;
		case 17:
			ValidateRemoveTime(lvalue, utils);
			break;
		case 18:
			ValidateEntryTime(lvalue, utils);
			break;
		case 19:
			ValidateFixed(lvalue, utils);
			break;
		case 20:
			ValidateWasCancelled(lvalue, utils);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<Downtime>::NotifyField(int id, const Value& cookie)
{
	int real_id = id - ConfigObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { ConfigObject::NotifyField(id, cookie); return; }
	switch (real_id) {
		case 0:
			NotifyTriggeredBy(cookie);
			break;
		case 1:
			NotifyRemovedBy(cookie);
			break;
		case 2:
			NotifyAuthoritativeZone(cookie);
			break;
		case 3:
			NotifyConfigOwnerHash(cookie);
			break;
		case 4:
			NotifyConfigOwner(cookie);
			break;
		case 5:
			NotifyParent(cookie);
			break;
		case 6:
			NotifyScheduledBy(cookie);
			break;
		case 7:
			NotifyHostName(cookie);
			break;
		case 8:
			NotifyComment(cookie);
			break;
		case 9:
			NotifyAuthor(cookie);
			break;
		case 10:
			NotifyServiceName(cookie);
			break;
		case 11:
			NotifyTriggers(cookie);
			break;
		case 12:
			NotifyLegacyId(cookie);
			break;
		case 13:
			NotifyDuration(cookie);
			break;
		case 14:
			NotifyTriggerTime(cookie);
			break;
		case 15:
			NotifyEndTime(cookie);
			break;
		case 16:
			NotifyStartTime(cookie);
			break;
		case 17:
			NotifyRemoveTime(cookie);
			break;
		case 18:
			NotifyEntryTime(cookie);
			break;
		case 19:
			NotifyFixed(cookie);
			break;
		case 20:
			NotifyWasCancelled(cookie);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

Object::Ptr ObjectImpl<Downtime>::NavigateField(int id) const
{
	int real_id = id - ConfigObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { return ConfigObject::NavigateField(id); }
	switch (real_id) {
		case 7:
			return NavigateHostName();
		case 10:
			return NavigateServiceName();
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

String ObjectImpl<Downtime>::GetTriggeredBy() const
{
	return m_TriggeredBy.load();
}

String ObjectImpl<Downtime>::GetRemovedBy() const
{
	return m_RemovedBy.load();
}

String ObjectImpl<Downtime>::GetAuthoritativeZone() const
{
	return m_AuthoritativeZone.load();
}

String ObjectImpl<Downtime>::GetConfigOwnerHash() const
{
	return m_ConfigOwnerHash.load();
}

String ObjectImpl<Downtime>::GetConfigOwner() const
{
	return m_ConfigOwner.load();
}

String ObjectImpl<Downtime>::GetParent() const
{
	return m_Parent.load();
}

String ObjectImpl<Downtime>::GetScheduledBy() const
{
	return m_ScheduledBy.load();
}

String ObjectImpl<Downtime>::GetHostName() const
{
	return m_HostName.load();
}

String ObjectImpl<Downtime>::GetComment() const
{
	return m_Comment.load();
}

String ObjectImpl<Downtime>::GetAuthor() const
{
	return m_Author.load();
}

String ObjectImpl<Downtime>::GetServiceName() const
{
	return m_ServiceName.load();
}

Array::Ptr ObjectImpl<Downtime>::GetTriggers() const
{
	return m_Triggers.load();
}

int ObjectImpl<Downtime>::GetLegacyId() const
{
	return m_LegacyId.load();
}

Timestamp ObjectImpl<Downtime>::GetDuration() const
{
	return m_Duration.load();
}

Timestamp ObjectImpl<Downtime>::GetTriggerTime() const
{
	return m_TriggerTime.load();
}

Timestamp ObjectImpl<Downtime>::GetEndTime() const
{
	return m_EndTime.load();
}

Timestamp ObjectImpl<Downtime>::GetStartTime() const
{
	return m_StartTime.load();
}

Timestamp ObjectImpl<Downtime>::GetRemoveTime() const
{
	return m_RemoveTime.load();
}

Timestamp ObjectImpl<Downtime>::GetEntryTime() const
{
	return m_EntryTime.load();
}

bool ObjectImpl<Downtime>::GetFixed() const
{
	return m_Fixed.load();
}

bool ObjectImpl<Downtime>::GetWasCancelled() const
{
 return GetRemoveTime() > 0; 
}

void ObjectImpl<Downtime>::SetTriggeredBy(const String& value, bool suppress_events, const Value& cookie)
{
	m_TriggeredBy.store(value);
	if (!suppress_events) {
		NotifyTriggeredBy(cookie);
	}

}

void ObjectImpl<Downtime>::SetRemovedBy(const String& value, bool suppress_events, const Value& cookie)
{
	m_RemovedBy.store(value);
	if (!suppress_events) {
		NotifyRemovedBy(cookie);
	}

}

void ObjectImpl<Downtime>::SetAuthoritativeZone(const String& value, bool suppress_events, const Value& cookie)
{
	m_AuthoritativeZone.store(value);
	if (!suppress_events) {
		NotifyAuthoritativeZone(cookie);
	}

}

void ObjectImpl<Downtime>::SetConfigOwnerHash(const String& value, bool suppress_events, const Value& cookie)
{
	m_ConfigOwnerHash.store(value);
	if (!suppress_events) {
		NotifyConfigOwnerHash(cookie);
	}

}

void ObjectImpl<Downtime>::SetConfigOwner(const String& value, bool suppress_events, const Value& cookie)
{
	m_ConfigOwner.store(value);
	if (!suppress_events) {
		NotifyConfigOwner(cookie);
	}

}

void ObjectImpl<Downtime>::SetParent(const String& value, bool suppress_events, const Value& cookie)
{
	m_Parent.store(value);
	if (!suppress_events) {
		NotifyParent(cookie);
	}

}

void ObjectImpl<Downtime>::SetScheduledBy(const String& value, bool suppress_events, const Value& cookie)
{
	m_ScheduledBy.store(value);
	if (!suppress_events) {
		NotifyScheduledBy(cookie);
	}

}

void ObjectImpl<Downtime>::SetHostName(const String& value, bool suppress_events, const Value& cookie)
{
	Value oldValue = GetHostName();
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	m_HostName.store(value);
	if (!dobj || dobj->IsActive())
		TrackHostName(oldValue, value);
	if (!suppress_events) {
		NotifyHostName(cookie);
	}

}

void ObjectImpl<Downtime>::SetComment(const String& value, bool suppress_events, const Value& cookie)
{
	m_Comment.store(value);
	if (!suppress_events) {
		NotifyComment(cookie);
	}

}

void ObjectImpl<Downtime>::SetAuthor(const String& value, bool suppress_events, const Value& cookie)
{
	m_Author.store(value);
	if (!suppress_events) {
		NotifyAuthor(cookie);
	}

}

void ObjectImpl<Downtime>::SetServiceName(const String& value, bool suppress_events, const Value& cookie)
{
	Value oldValue = GetServiceName();
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	m_ServiceName.store(value);
	if (!dobj || dobj->IsActive())
		TrackServiceName(oldValue, value);
	if (!suppress_events) {
		NotifyServiceName(cookie);
	}

}

void ObjectImpl<Downtime>::SetTriggers(const Array::Ptr& value, bool suppress_events, const Value& cookie)
{
	m_Triggers.store(value);
	if (!suppress_events) {
		NotifyTriggers(cookie);
	}

}

void ObjectImpl<Downtime>::SetLegacyId(int value, bool suppress_events, const Value& cookie)
{
	m_LegacyId.store(value);
	if (!suppress_events) {
		NotifyLegacyId(cookie);
	}

}

void ObjectImpl<Downtime>::SetDuration(const Timestamp& value, bool suppress_events, const Value& cookie)
{
	m_Duration.store(value);
	if (!suppress_events) {
		NotifyDuration(cookie);
	}

}

void ObjectImpl<Downtime>::SetTriggerTime(const Timestamp& value, bool suppress_events, const Value& cookie)
{
	m_TriggerTime.store(value);
	if (!suppress_events) {
		NotifyTriggerTime(cookie);
	}

}

void ObjectImpl<Downtime>::SetEndTime(const Timestamp& value, bool suppress_events, const Value& cookie)
{
	m_EndTime.store(value);
	if (!suppress_events) {
		NotifyEndTime(cookie);
	}

}

void ObjectImpl<Downtime>::SetStartTime(const Timestamp& value, bool suppress_events, const Value& cookie)
{
	m_StartTime.store(value);
	if (!suppress_events) {
		NotifyStartTime(cookie);
	}

}

void ObjectImpl<Downtime>::SetRemoveTime(const Timestamp& value, bool suppress_events, const Value& cookie)
{
	m_RemoveTime.store(value);
	if (!suppress_events) {
		NotifyRemoveTime(cookie);
	}

}

void ObjectImpl<Downtime>::SetEntryTime(const Timestamp& value, bool suppress_events, const Value& cookie)
{
	m_EntryTime.store(value);
	if (!suppress_events) {
		NotifyEntryTime(cookie);
	}

}

void ObjectImpl<Downtime>::SetFixed(bool value, bool suppress_events, const Value& cookie)
{
	m_Fixed.store(value);
	if (!suppress_events) {
		NotifyFixed(cookie);
	}

}

void ObjectImpl<Downtime>::SetWasCancelled(bool value, bool suppress_events, const Value& cookie)
{


	if (!suppress_events) {
		NotifyWasCancelled(cookie);
	}

}

void ObjectImpl<Downtime>::TrackHostName(const String& oldValue, const String& newValue)
{
	if (!oldValue.IsEmpty())
		DependencyGraph::RemoveDependency(this, ConfigObject::GetObject<Host>(oldValue).get());
	if (!newValue.IsEmpty())
		DependencyGraph::AddDependency(this, ConfigObject::GetObject<Host>(newValue).get());
}

void ObjectImpl<Downtime>::TrackServiceName(const String& oldValue, const String& newValue)
{
	
			if (!oldValue.IsEmpty()) {
				Service::Ptr service = Service::GetByNamePair(GetHostName(), oldValue);
				DependencyGraph::RemoveDependency(this, service.get());
			}

			if (!newValue.IsEmpty()) {
				Service::Ptr service = Service::GetByNamePair(GetHostName(), newValue);
				DependencyGraph::AddDependency(this, service.get());
			}
		
}

Object::Ptr ObjectImpl<Downtime>::NavigateHostName() const
{
	
			return Host::GetByName(GetHostName());
		
}

Object::Ptr ObjectImpl<Downtime>::NavigateServiceName() const
{
	
			if (!GetServiceName().IsEmpty()) {
				Host::Ptr host = Host::GetByName(GetHostName());
				if (host)
					return host->GetServiceByShortName(GetServiceName());
			}

			return nullptr;
		
}

void ObjectImpl<Downtime>::Start(bool runtimeCreated)
{
	ConfigObject::Start(runtimeCreated);

	TrackHostName(Empty, GetHostName());
	TrackServiceName(Empty, GetServiceName());
}

void ObjectImpl<Downtime>::Stop(bool runtimeRemoved)
{
	ConfigObject::Stop(runtimeRemoved);

	TrackHostName(GetHostName(), Empty);
	TrackServiceName(GetServiceName(), Empty);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

String ObjectImpl<Downtime>::GetDefaultTriggeredBy() const
{
	return String();
}

String ObjectImpl<Downtime>::GetDefaultRemovedBy() const
{
	return String();
}

String ObjectImpl<Downtime>::GetDefaultAuthoritativeZone() const
{
	return String();
}

String ObjectImpl<Downtime>::GetDefaultConfigOwnerHash() const
{
	return String();
}

String ObjectImpl<Downtime>::GetDefaultConfigOwner() const
{
	return String();
}

String ObjectImpl<Downtime>::GetDefaultParent() const
{
	return String();
}

String ObjectImpl<Downtime>::GetDefaultScheduledBy() const
{
	return String();
}

String ObjectImpl<Downtime>::GetDefaultHostName() const
{
	return String();
}

String ObjectImpl<Downtime>::GetDefaultComment() const
{
	return String();
}

String ObjectImpl<Downtime>::GetDefaultAuthor() const
{
	return String();
}

String ObjectImpl<Downtime>::GetDefaultServiceName() const
{
	return String();
}

Array::Ptr ObjectImpl<Downtime>::GetDefaultTriggers() const
{
	 return new Array(); 
}

int ObjectImpl<Downtime>::GetDefaultLegacyId() const
{
	return int();
}

Timestamp ObjectImpl<Downtime>::GetDefaultDuration() const
{
	return Timestamp();
}

Timestamp ObjectImpl<Downtime>::GetDefaultTriggerTime() const
{
	return Timestamp();
}

Timestamp ObjectImpl<Downtime>::GetDefaultEndTime() const
{
	return Timestamp();
}

Timestamp ObjectImpl<Downtime>::GetDefaultStartTime() const
{
	return Timestamp();
}

Timestamp ObjectImpl<Downtime>::GetDefaultRemoveTime() const
{
	return Timestamp();
}

Timestamp ObjectImpl<Downtime>::GetDefaultEntryTime() const
{
	 return Utility::GetTime(); 
}

bool ObjectImpl<Downtime>::GetDefaultFixed() const
{
	return bool();
}

bool ObjectImpl<Downtime>::GetDefaultWasCancelled() const
{
	return bool();
}


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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

void ObjectImpl<Downtime>::ValidateAuthor(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateAuthor(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateAuthoritativeZone(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateAuthoritativeZone(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateComment(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateComment(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateConfigOwner(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateConfigOwner(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateConfigOwnerHash(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateConfigOwnerHash(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateDuration(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateDuration(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateEndTime(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateEndTime(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateEntryTime(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateEntryTime(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateFixed(const Lazy<bool>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateFixed(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateHostName(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateHostName(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateLegacyId(const Lazy<int>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateLegacyId(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateParent(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateParent(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateRemoveTime(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateRemoveTime(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateRemovedBy(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateRemovedBy(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateScheduledBy(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateScheduledBy(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateServiceName(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateServiceName(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateStartTime(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateStartTime(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateTriggerTime(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateTriggerTime(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateTriggeredBy(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateTriggeredBy(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateTriggers(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateTriggers(lvalue, utils);
}

void ObjectImpl<Downtime>::ValidateWasCancelled(const Lazy<bool>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateWasCancelled(lvalue, utils);
}

}
#pragma GCC diagnostic pop
