#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<Dependency>::TypeImpl()
{ }

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

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

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

Type::Ptr TypeImpl<Dependency>::GetBaseType() const
{
	return CustomVarObject::TypeInstance;
}

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

	switch (static_cast<int>(Utility::SDBM(name, 2))) {
		case 6494405:
			if (name == "child_host_name")
				return offset + 0;
			if (name == "child_service_name")
				return offset + 1;

			break;
		case 6560005:
			if (name == "disable_checks")
				return offset + 9;
			if (name == "disable_notifications")
				return offset + 10;

			break;
		case 6887998:
			if (name == "ignore_soft_states")
				return offset + 8;

			break;
		case 7347185:
			if (name == "parent_host_name")
				return offset + 2;
			if (name == "parent_service_name")
				return offset + 3;

			break;
		case 7347189:
			if (name == "period")
				return offset + 5;

			break;
		case 7478387:
			if (name == "redundancy_group")
				return offset + 4;

			break;
		case 7544001:
			if (name == "states")
				return offset + 6;
			if (name == "state_filter_real")
				return offset + 7;

			break;
	}

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

Field TypeImpl<Dependency>::GetFieldInfo(int id) const
{
	int real_id = id - CustomVarObject::TypeInstance->GetFieldCount();
	if (real_id < 0) { return CustomVarObject::TypeInstance->GetFieldInfo(id); }
	switch (real_id) {
		case 0:
			return {0, "String", "child_host_name", "child_host", "Host", 1794, 0};
		case 1:
			return {1, "String", "child_service_name", "child_service", nullptr, 1538, 0};
		case 2:
			return {2, "String", "parent_host_name", "parent_host", "Host", 1794, 0};
		case 3:
			return {3, "String", "parent_service_name", "parent_service", nullptr, 1538, 0};
		case 4:
			return {4, "String", "redundancy_group", "redundancy_group", nullptr, 1026, 0};
		case 5:
			return {5, "String", "period", "period", "TimePeriod", 1538, 0};
		case 6:
			return {6, "Array", "states", "states", nullptr, 1026, 1};
		case 7:
			return {7, "Number", "state_filter_real", "state_filter_real", nullptr, 3073, 0};
		case 8:
			return {8, "Boolean", "ignore_soft_states", "ignore_soft_states", nullptr, 1026, 0};
		case 9:
			return {9, "Boolean", "disable_checks", "disable_checks", nullptr, 2, 0};
		case 10:
			return {10, "Boolean", "disable_notifications", "disable_notifications", nullptr, 2, 0};
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

int TypeImpl<Dependency>::GetFieldCount() const
{
	return 11 + CustomVarObject::TypeInstance->GetFieldCount();
}

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

const std::unordered_set<Type*>& TypeImpl<Dependency>::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<Dependency>::GetActivationPriority() const
{
	return -10;
}

void TypeImpl<Dependency>::RegisterAttributeHandler(int fieldId, const Type::AttributeHandler& callback)
{
	int real_id = fieldId - CustomVarObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { CustomVarObject::TypeInstance->RegisterAttributeHandler(fieldId, callback); return; }
	switch (real_id) {
		case 0:
			ObjectImpl<Dependency>::OnChildHostNameChanged.connect(callback);
			break;
		case 1:
			ObjectImpl<Dependency>::OnChildServiceNameChanged.connect(callback);
			break;
		case 2:
			ObjectImpl<Dependency>::OnParentHostNameChanged.connect(callback);
			break;
		case 3:
			ObjectImpl<Dependency>::OnParentServiceNameChanged.connect(callback);
			break;
		case 4:
			ObjectImpl<Dependency>::OnRedundancyGroupChanged.connect(callback);
			break;
		case 5:
			ObjectImpl<Dependency>::OnPeriodRawChanged.connect(callback);
			break;
		case 6:
			ObjectImpl<Dependency>::OnStatesChanged.connect(callback);
			break;
		case 7:
			ObjectImpl<Dependency>::OnStateFilterChanged.connect(callback);
			break;
		case 8:
			ObjectImpl<Dependency>::OnIgnoreSoftStatesChanged.connect(callback);
			break;
		case 9:
			ObjectImpl<Dependency>::OnDisableChecksChanged.connect(callback);
			break;
		case 10:
			ObjectImpl<Dependency>::OnDisableNotificationsChanged.connect(callback);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

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

	if (2 & types)
		ValidateChildHostName(Lazy<String>([this]() { return GetChildHostName(); }), utils);
	if (2 & types)
		ValidateChildServiceName(Lazy<String>([this]() { return GetChildServiceName(); }), utils);
	if (2 & types)
		ValidateParentHostName(Lazy<String>([this]() { return GetParentHostName(); }), utils);
	if (2 & types)
		ValidateParentServiceName(Lazy<String>([this]() { return GetParentServiceName(); }), utils);
	if (2 & types)
		ValidateRedundancyGroup(Lazy<String>([this]() { return GetRedundancyGroup(); }), utils);
	if (2 & types)
		ValidatePeriodRaw(Lazy<String>([this]() { return GetPeriodRaw(); }), utils);
	if (2 & types)
		ValidateStates(Lazy<Array::Ptr>([this]() { return GetStates(); }), utils);
	if (1 & types)
		ValidateStateFilter(Lazy<int>([this]() { return GetStateFilter(); }), utils);
	if (2 & types)
		ValidateIgnoreSoftStates(Lazy<bool>([this]() { return GetIgnoreSoftStates(); }), utils);
	if (2 & types)
		ValidateDisableChecks(Lazy<bool>([this]() { return GetDisableChecks(); }), utils);
	if (2 & types)
		ValidateDisableNotifications(Lazy<bool>([this]() { return GetDisableNotifications(); }), utils);
}

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

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

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

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

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

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

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

void ObjectImpl<Dependency>::SimpleValidatePeriodRaw(const Lazy<String>& value, const ValidationUtils& utils)
{
			if (!value().IsEmpty() && !utils.ValidateName("TimePeriod", value()))
				BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "period" }, "Object '" + value() + "' of type 'TimePeriod' does not exist."));
}

void ObjectImpl<Dependency>::SimpleValidateStates(const Lazy<Array::Ptr>& avalue, const ValidationUtils& utils)
{
	if (avalue()) {
		ObjectLock olock(avalue());
		for (const Value& value : avalue()) {
	if (value.IsObjectType<Function>()) {
		Function::Ptr func = value;
		if (func->IsDeprecated())
			Log(LogWarning, "Dependency") << "Attribute 'states' for object '" << dynamic_cast<ConfigObject *>(this)->GetName() << "' of type '" << dynamic_cast<ConfigObject *>(this)->GetReflectionType()->GetName() << "' is set to a deprecated function: " << func->GetName();
	}

		}
	}
}

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

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

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

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

ObjectImpl<Dependency>::ObjectImpl()
{
	SetChildHostName(GetDefaultChildHostName(), true);
	SetChildServiceName(GetDefaultChildServiceName(), true);
	SetParentHostName(GetDefaultParentHostName(), true);
	SetParentServiceName(GetDefaultParentServiceName(), true);
	SetRedundancyGroup(GetDefaultRedundancyGroup(), true);
	SetPeriodRaw(GetDefaultPeriodRaw(), true);
	SetStates(GetDefaultStates(), true);
	SetStateFilter(GetDefaultStateFilter(), true);
	SetIgnoreSoftStates(GetDefaultIgnoreSoftStates(), true);
	SetDisableChecks(GetDefaultDisableChecks(), true);
	SetDisableNotifications(GetDefaultDisableNotifications(), true);
}

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

void ObjectImpl<Dependency>::SetField(int id, const Value& value, bool suppress_events, const Value& cookie)
{
	int real_id = id - CustomVarObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { CustomVarObject::SetField(id, value, suppress_events, cookie); return; }
	switch (real_id) {
		case 0:
			SetChildHostName(value, suppress_events, cookie);
			break;
		case 1:
			SetChildServiceName(value, suppress_events, cookie);
			break;
		case 2:
			SetParentHostName(value, suppress_events, cookie);
			break;
		case 3:
			SetParentServiceName(value, suppress_events, cookie);
			break;
		case 4:
			SetRedundancyGroup(value, suppress_events, cookie);
			break;
		case 5:
			SetPeriodRaw(value, suppress_events, cookie);
			break;
		case 6:
			SetStates(value, suppress_events, cookie);
			break;
		case 7:
			SetStateFilter(value, suppress_events, cookie);
			break;
		case 8:
			SetIgnoreSoftStates(value, suppress_events, cookie);
			break;
		case 9:
			SetDisableChecks(value, suppress_events, cookie);
			break;
		case 10:
			SetDisableNotifications(value, suppress_events, cookie);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

Value ObjectImpl<Dependency>::GetField(int id) const
{
	int real_id = id - CustomVarObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { return CustomVarObject::GetField(id); }
	switch (real_id) {
		case 0:
			return GetChildHostName();
		case 1:
			return GetChildServiceName();
		case 2:
			return GetParentHostName();
		case 3:
			return GetParentServiceName();
		case 4:
			return GetRedundancyGroup();
		case 5:
			return GetPeriodRaw();
		case 6:
			return GetStates();
		case 7:
			return GetStateFilter();
		case 8:
			return GetIgnoreSoftStates();
		case 9:
			return GetDisableChecks();
		case 10:
			return GetDisableNotifications();
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<Dependency>::ValidateField(int id, const Lazy<Value>& lvalue, const ValidationUtils& utils)
{
	int real_id = id - CustomVarObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { CustomVarObject::ValidateField(id, lvalue, utils); return; }
	switch (real_id) {
		case 0:
			ValidateChildHostName(lvalue, utils);
			break;
		case 1:
			ValidateChildServiceName(lvalue, utils);
			break;
		case 2:
			ValidateParentHostName(lvalue, utils);
			break;
		case 3:
			ValidateParentServiceName(lvalue, utils);
			break;
		case 4:
			ValidateRedundancyGroup(lvalue, utils);
			break;
		case 5:
			ValidatePeriodRaw(lvalue, utils);
			break;
		case 6:
			ValidateStates(lvalue, utils);
			break;
		case 7:
			ValidateStateFilter(lvalue, utils);
			break;
		case 8:
			ValidateIgnoreSoftStates(lvalue, utils);
			break;
		case 9:
			ValidateDisableChecks(lvalue, utils);
			break;
		case 10:
			ValidateDisableNotifications(lvalue, utils);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<Dependency>::NotifyField(int id, const Value& cookie)
{
	int real_id = id - CustomVarObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { CustomVarObject::NotifyField(id, cookie); return; }
	switch (real_id) {
		case 0:
			NotifyChildHostName(cookie);
			break;
		case 1:
			NotifyChildServiceName(cookie);
			break;
		case 2:
			NotifyParentHostName(cookie);
			break;
		case 3:
			NotifyParentServiceName(cookie);
			break;
		case 4:
			NotifyRedundancyGroup(cookie);
			break;
		case 5:
			NotifyPeriodRaw(cookie);
			break;
		case 6:
			NotifyStates(cookie);
			break;
		case 7:
			NotifyStateFilter(cookie);
			break;
		case 8:
			NotifyIgnoreSoftStates(cookie);
			break;
		case 9:
			NotifyDisableChecks(cookie);
			break;
		case 10:
			NotifyDisableNotifications(cookie);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

Object::Ptr ObjectImpl<Dependency>::NavigateField(int id) const
{
	int real_id = id - CustomVarObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { return CustomVarObject::NavigateField(id); }
	switch (real_id) {
		case 0:
			return NavigateChildHostName();
		case 1:
			return NavigateChildServiceName();
		case 2:
			return NavigateParentHostName();
		case 3:
			return NavigateParentServiceName();
		case 5:
			return NavigatePeriodRaw();
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

String ObjectImpl<Dependency>::GetChildHostName() const
{
	return m_ChildHostName.load();
}

String ObjectImpl<Dependency>::GetChildServiceName() const
{
	return m_ChildServiceName.load();
}

String ObjectImpl<Dependency>::GetParentHostName() const
{
	return m_ParentHostName.load();
}

String ObjectImpl<Dependency>::GetParentServiceName() const
{
	return m_ParentServiceName.load();
}

String ObjectImpl<Dependency>::GetRedundancyGroup() const
{
	return m_RedundancyGroup.load();
}

String ObjectImpl<Dependency>::GetPeriodRaw() const
{
	return m_PeriodRaw.load();
}

Array::Ptr ObjectImpl<Dependency>::GetStates() const
{
	return m_States.load();
}

int ObjectImpl<Dependency>::GetStateFilter() const
{
	return m_StateFilter.load();
}

bool ObjectImpl<Dependency>::GetIgnoreSoftStates() const
{
	return m_IgnoreSoftStates.load();
}

bool ObjectImpl<Dependency>::GetDisableChecks() const
{
	return m_DisableChecks.load();
}

bool ObjectImpl<Dependency>::GetDisableNotifications() const
{
	return m_DisableNotifications.load();
}

void ObjectImpl<Dependency>::SetChildHostName(const String& value, bool suppress_events, const Value& cookie)
{
	Value oldValue = GetChildHostName();
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	m_ChildHostName.store(value);
	if (!dobj || dobj->IsActive())
		TrackChildHostName(oldValue, value);
	if (!suppress_events) {
		NotifyChildHostName(cookie);
	}

}

void ObjectImpl<Dependency>::SetChildServiceName(const String& value, bool suppress_events, const Value& cookie)
{
	Value oldValue = GetChildServiceName();
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	m_ChildServiceName.store(value);
	if (!dobj || dobj->IsActive())
		TrackChildServiceName(oldValue, value);
	if (!suppress_events) {
		NotifyChildServiceName(cookie);
	}

}

void ObjectImpl<Dependency>::SetParentHostName(const String& value, bool suppress_events, const Value& cookie)
{
	Value oldValue = GetParentHostName();
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	m_ParentHostName.store(value);
	if (!dobj || dobj->IsActive())
		TrackParentHostName(oldValue, value);
	if (!suppress_events) {
		NotifyParentHostName(cookie);
	}

}

void ObjectImpl<Dependency>::SetParentServiceName(const String& value, bool suppress_events, const Value& cookie)
{
	Value oldValue = GetParentServiceName();
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	m_ParentServiceName.store(value);
	if (!dobj || dobj->IsActive())
		TrackParentServiceName(oldValue, value);
	if (!suppress_events) {
		NotifyParentServiceName(cookie);
	}

}

void ObjectImpl<Dependency>::SetRedundancyGroup(const String& value, bool suppress_events, const Value& cookie)
{
	m_RedundancyGroup.store(value);
	if (!suppress_events) {
		NotifyRedundancyGroup(cookie);
	}

}

void ObjectImpl<Dependency>::SetPeriodRaw(const String& value, bool suppress_events, const Value& cookie)
{
	Value oldValue = GetPeriodRaw();
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	m_PeriodRaw.store(value);
	if (!dobj || dobj->IsActive())
		TrackPeriodRaw(oldValue, value);
	if (!suppress_events) {
		NotifyPeriodRaw(cookie);
	}

}

void ObjectImpl<Dependency>::SetStates(const Array::Ptr& value, bool suppress_events, const Value& cookie)
{
	m_States.store(value);
	if (!suppress_events) {
		NotifyStates(cookie);
	}

}

void ObjectImpl<Dependency>::SetStateFilter(int value, bool suppress_events, const Value& cookie)
{
	m_StateFilter.store(value);
	if (!suppress_events) {
		NotifyStateFilter(cookie);
	}

}

void ObjectImpl<Dependency>::SetIgnoreSoftStates(bool value, bool suppress_events, const Value& cookie)
{
	m_IgnoreSoftStates.store(value);
	if (!suppress_events) {
		NotifyIgnoreSoftStates(cookie);
	}

}

void ObjectImpl<Dependency>::SetDisableChecks(bool value, bool suppress_events, const Value& cookie)
{
	m_DisableChecks.store(value);
	if (!suppress_events) {
		NotifyDisableChecks(cookie);
	}

}

void ObjectImpl<Dependency>::SetDisableNotifications(bool value, bool suppress_events, const Value& cookie)
{
	m_DisableNotifications.store(value);
	if (!suppress_events) {
		NotifyDisableNotifications(cookie);
	}

}

void ObjectImpl<Dependency>::TrackChildHostName(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<Dependency>::TrackChildServiceName(const String& oldValue, const String& newValue)
{
	
			if (!oldValue.IsEmpty()) {
				Service::Ptr service = Service::GetByNamePair(GetChildHostName(), oldValue);
				DependencyGraph::RemoveDependency(this, service.get());
			}

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

void ObjectImpl<Dependency>::TrackParentHostName(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<Dependency>::TrackParentServiceName(const String& oldValue, const String& newValue)
{
	
			if (!oldValue.IsEmpty()) {
				Service::Ptr service = Service::GetByNamePair(GetParentHostName(), oldValue);
				DependencyGraph::RemoveDependency(this, service.get());
			}

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

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

Object::Ptr ObjectImpl<Dependency>::NavigateChildHostName() const
{
	
			return Host::GetByName(GetChildHostName());
		
}

Object::Ptr ObjectImpl<Dependency>::NavigateChildServiceName() const
{
	
			if (!GetChildServiceName().IsEmpty()) {
				Host::Ptr host = Host::GetByName(GetChildHostName());
				if (host)
					return host->GetServiceByShortName(GetChildServiceName());
			}

			return nullptr;
		
}

Object::Ptr ObjectImpl<Dependency>::NavigateParentHostName() const
{
	
			return Host::GetByName(GetParentHostName());
		
}

Object::Ptr ObjectImpl<Dependency>::NavigateParentServiceName() const
{
	
			if (!GetParentServiceName().IsEmpty()) {
				Host::Ptr host = Host::GetByName(GetParentHostName());
				if (host)
					return host->GetServiceByShortName(GetParentServiceName());
			}

			return nullptr;
		
}

Object::Ptr ObjectImpl<Dependency>::NavigatePeriodRaw() const
{
	
			return TimePeriod::GetByName(GetPeriodRaw());
		
}

void ObjectImpl<Dependency>::Start(bool runtimeCreated)
{
	CustomVarObject::Start(runtimeCreated);

	TrackChildHostName(Empty, GetChildHostName());
	TrackChildServiceName(Empty, GetChildServiceName());
	TrackParentHostName(Empty, GetParentHostName());
	TrackParentServiceName(Empty, GetParentServiceName());
	TrackPeriodRaw(Empty, GetPeriodRaw());
}

void ObjectImpl<Dependency>::Stop(bool runtimeRemoved)
{
	CustomVarObject::Stop(runtimeRemoved);

	TrackChildHostName(GetChildHostName(), Empty);
	TrackChildServiceName(GetChildServiceName(), Empty);
	TrackParentHostName(GetParentHostName(), Empty);
	TrackParentServiceName(GetParentServiceName(), Empty);
	TrackPeriodRaw(GetPeriodRaw(), Empty);
}

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

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

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

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

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

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

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

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

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

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

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

String ObjectImpl<Dependency>::GetDefaultChildHostName() const
{
	return String();
}

String ObjectImpl<Dependency>::GetDefaultChildServiceName() const
{
	return String();
}

String ObjectImpl<Dependency>::GetDefaultParentHostName() const
{
	return String();
}

String ObjectImpl<Dependency>::GetDefaultParentServiceName() const
{
	return String();
}

String ObjectImpl<Dependency>::GetDefaultRedundancyGroup() const
{
	return String();
}

String ObjectImpl<Dependency>::GetDefaultPeriodRaw() const
{
	return String();
}

Array::Ptr ObjectImpl<Dependency>::GetDefaultStates() const
{
	return Array::Ptr();
}

int ObjectImpl<Dependency>::GetDefaultStateFilter() const
{
	return int();
}

bool ObjectImpl<Dependency>::GetDefaultIgnoreSoftStates() const
{
	 return true; 
}

bool ObjectImpl<Dependency>::GetDefaultDisableChecks() const
{
	return bool();
}

bool ObjectImpl<Dependency>::GetDefaultDisableNotifications() const
{
	 return true; 
}


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


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


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


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


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


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


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


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


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


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


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

void ObjectImpl<Dependency>::ValidateChildHostName(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateChildHostName(lvalue, utils);
}

void ObjectImpl<Dependency>::ValidateChildServiceName(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateChildServiceName(lvalue, utils);
}

void ObjectImpl<Dependency>::ValidateDisableChecks(const Lazy<bool>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateDisableChecks(lvalue, utils);
}

void ObjectImpl<Dependency>::ValidateDisableNotifications(const Lazy<bool>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateDisableNotifications(lvalue, utils);
}

void ObjectImpl<Dependency>::ValidateIgnoreSoftStates(const Lazy<bool>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateIgnoreSoftStates(lvalue, utils);
}

void ObjectImpl<Dependency>::ValidateParentHostName(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateParentHostName(lvalue, utils);
}

void ObjectImpl<Dependency>::ValidateParentServiceName(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateParentServiceName(lvalue, utils);
}

void ObjectImpl<Dependency>::ValidatePeriodRaw(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidatePeriodRaw(lvalue, utils);
}

void ObjectImpl<Dependency>::ValidateRedundancyGroup(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateRedundancyGroup(lvalue, utils);
}

void ObjectImpl<Dependency>::ValidateStateFilter(const Lazy<int>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateStateFilter(lvalue, utils);
}

void ObjectImpl<Dependency>::ValidateStates(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateStates(lvalue, utils);
}

}
#pragma GCC diagnostic pop
