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

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

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

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

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

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

	switch (static_cast<int>(Utility::SDBM(name, 1))) {
		case 97:
			if (name == "author")
				return offset + 3;

			break;
		case 99:
			if (name == "child_options")
				return offset + 0;
			if (name == "comment")
				return offset + 4;

			break;
		case 100:
			if (name == "duration")
				return offset + 5;

			break;
		case 102:
			if (name == "fixed")
				return offset + 7;

			break;
		case 104:
			if (name == "host_name")
				return offset + 1;

			break;
		case 114:
			if (name == "ranges")
				return offset + 6;

			break;
		case 115:
			if (name == "service_name")
				return offset + 2;

			break;
	}

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

Field TypeImpl<ScheduledDowntime>::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, "Value", "child_options", "child_options", nullptr, 2, 0};
		case 1:
			return {1, "String", "host_name", "host", "Host", 1842, 0};
		case 2:
			return {2, "String", "service_name", "service", nullptr, 1586, 0};
		case 3:
			return {3, "String", "author", "author", nullptr, 258, 0};
		case 4:
			return {4, "String", "comment", "comment", nullptr, 258, 0};
		case 5:
			return {5, "Number", "duration", "duration", nullptr, 2, 0};
		case 6:
			return {6, "Dictionary", "ranges", "ranges", nullptr, 258, 0};
		case 7:
			return {7, "Boolean", "fixed", "fixed", nullptr, 2, 0};
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

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

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

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

void TypeImpl<ScheduledDowntime>::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<ScheduledDowntime>::OnChildOptionsChanged.connect(callback);
			break;
		case 1:
			ObjectImpl<ScheduledDowntime>::OnHostNameChanged.connect(callback);
			break;
		case 2:
			ObjectImpl<ScheduledDowntime>::OnServiceNameChanged.connect(callback);
			break;
		case 3:
			ObjectImpl<ScheduledDowntime>::OnAuthorChanged.connect(callback);
			break;
		case 4:
			ObjectImpl<ScheduledDowntime>::OnCommentChanged.connect(callback);
			break;
		case 5:
			ObjectImpl<ScheduledDowntime>::OnDurationChanged.connect(callback);
			break;
		case 6:
			ObjectImpl<ScheduledDowntime>::OnRangesChanged.connect(callback);
			break;
		case 7:
			ObjectImpl<ScheduledDowntime>::OnFixedChanged.connect(callback);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

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

	if (2 & types)
		ValidateChildOptions(Lazy<Value>([this]() { return GetChildOptions(); }), utils);
	if (2 & types)
		ValidateHostName(Lazy<String>([this]() { return GetHostName(); }), utils);
	if (2 & types)
		ValidateServiceName(Lazy<String>([this]() { return GetServiceName(); }), utils);
	if (2 & types)
		ValidateAuthor(Lazy<String>([this]() { return GetAuthor(); }), utils);
	if (2 & types)
		ValidateComment(Lazy<String>([this]() { return GetComment(); }), utils);
	if (2 & types)
		ValidateDuration(Lazy<double>([this]() { return GetDuration(); }), utils);
	if (2 & types)
		ValidateRanges(Lazy<Dictionary::Ptr>([this]() { return GetRanges(); }), utils);
	if (2 & types)
		ValidateFixed(Lazy<bool>([this]() { return GetFixed(); }), utils);
}

void ObjectImpl<ScheduledDowntime>::SimpleValidateChildOptions(const Lazy<Value>& value, const ValidationUtils& utils)
{
	if (value().IsObjectType<Function>()) {
		Function::Ptr func = value();
		if (func->IsDeprecated())
			Log(LogWarning, "ScheduledDowntime") << "Attribute 'child_options' 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<ScheduledDowntime>::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<ScheduledDowntime>::SimpleValidateServiceName(const Lazy<String>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<ScheduledDowntime>::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<ScheduledDowntime>::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<ScheduledDowntime>::SimpleValidateDuration(const Lazy<double>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<ScheduledDowntime>::SimpleValidateRanges(const Lazy<Dictionary::Ptr>& value, const ValidationUtils& utils)
{
	if (!value())
		BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "ranges" }, "Attribute must not be empty."));

}

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

ObjectImpl<ScheduledDowntime>::ObjectImpl()
{
	SetChildOptions(GetDefaultChildOptions(), true);
	SetHostName(GetDefaultHostName(), true);
	SetServiceName(GetDefaultServiceName(), true);
	SetAuthor(GetDefaultAuthor(), true);
	SetComment(GetDefaultComment(), true);
	SetDuration(GetDefaultDuration(), true);
	SetRanges(GetDefaultRanges(), true);
	SetFixed(GetDefaultFixed(), true);
}

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

void ObjectImpl<ScheduledDowntime>::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:
			SetChildOptions(value, suppress_events, cookie);
			break;
		case 1:
			SetHostName(value, suppress_events, cookie);
			break;
		case 2:
			SetServiceName(value, suppress_events, cookie);
			break;
		case 3:
			SetAuthor(value, suppress_events, cookie);
			break;
		case 4:
			SetComment(value, suppress_events, cookie);
			break;
		case 5:
			SetDuration(value, suppress_events, cookie);
			break;
		case 6:
			SetRanges(value, suppress_events, cookie);
			break;
		case 7:
			SetFixed(value, suppress_events, cookie);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

Value ObjectImpl<ScheduledDowntime>::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 GetChildOptions();
		case 1:
			return GetHostName();
		case 2:
			return GetServiceName();
		case 3:
			return GetAuthor();
		case 4:
			return GetComment();
		case 5:
			return GetDuration();
		case 6:
			return GetRanges();
		case 7:
			return GetFixed();
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<ScheduledDowntime>::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:
			ValidateChildOptions(lvalue, utils);
			break;
		case 1:
			ValidateHostName(lvalue, utils);
			break;
		case 2:
			ValidateServiceName(lvalue, utils);
			break;
		case 3:
			ValidateAuthor(lvalue, utils);
			break;
		case 4:
			ValidateComment(lvalue, utils);
			break;
		case 5:
			ValidateDuration(lvalue, utils);
			break;
		case 6:
			ValidateRanges(lvalue, utils);
			break;
		case 7:
			ValidateFixed(lvalue, utils);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<ScheduledDowntime>::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:
			NotifyChildOptions(cookie);
			break;
		case 1:
			NotifyHostName(cookie);
			break;
		case 2:
			NotifyServiceName(cookie);
			break;
		case 3:
			NotifyAuthor(cookie);
			break;
		case 4:
			NotifyComment(cookie);
			break;
		case 5:
			NotifyDuration(cookie);
			break;
		case 6:
			NotifyRanges(cookie);
			break;
		case 7:
			NotifyFixed(cookie);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

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

Value ObjectImpl<ScheduledDowntime>::GetChildOptions() const
{
	return m_ChildOptions.load();
}

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

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

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

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

double ObjectImpl<ScheduledDowntime>::GetDuration() const
{
	return m_Duration.load();
}

Dictionary::Ptr ObjectImpl<ScheduledDowntime>::GetRanges() const
{
	return m_Ranges.load();
}

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

void ObjectImpl<ScheduledDowntime>::SetChildOptions(const Value& value, bool suppress_events, const Value& cookie)
{
	m_ChildOptions.store(value);
	if (!suppress_events) {
		NotifyChildOptions(cookie);
	}

}

void ObjectImpl<ScheduledDowntime>::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<ScheduledDowntime>::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<ScheduledDowntime>::SetAuthor(const String& value, bool suppress_events, const Value& cookie)
{
	m_Author.store(value);
	if (!suppress_events) {
		NotifyAuthor(cookie);
	}

}

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

}

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

}

void ObjectImpl<ScheduledDowntime>::SetRanges(const Dictionary::Ptr& value, bool suppress_events, const Value& cookie)
{
	m_Ranges.store(value);
	if (!suppress_events) {
		NotifyRanges(cookie);
	}

}

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

}

void ObjectImpl<ScheduledDowntime>::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<ScheduledDowntime>::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<ScheduledDowntime>::NavigateHostName() const
{
	
			return Host::GetByName(GetHostName());
		
}

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

			return nullptr;
		
}

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

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

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

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

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

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

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

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

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

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

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

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

Value ObjectImpl<ScheduledDowntime>::GetDefaultChildOptions() const
{
	 return "DowntimeNoChildren"; 
}

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

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

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

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

double ObjectImpl<ScheduledDowntime>::GetDefaultDuration() const
{
	return double();
}

Dictionary::Ptr ObjectImpl<ScheduledDowntime>::GetDefaultRanges() const
{
	return Dictionary::Ptr();
}

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


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


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


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


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


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


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


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


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

static void TIValidateScheduledDowntime_1(const intrusive_ptr<ObjectImpl<ScheduledDowntime> >& object, const String& key, const Value& value, std::vector<String>& location, const ValidationUtils& utils)
{
	bool known_attribute = false;
	do {
		known_attribute = true;
		if (value.IsEmpty() || value.IsScalar())
			return;
	} while (0);

	if (!known_attribute)
		BOOST_THROW_EXCEPTION(ValidationError(dynamic_pointer_cast<ConfigObject>(object), location, "Invalid attribute: " + key));
	else
		BOOST_THROW_EXCEPTION(ValidationError(dynamic_pointer_cast<ConfigObject>(object), location, "Invalid type."));
}

static void TIValidateScheduledDowntimeAuthor(const intrusive_ptr<ObjectImpl<ScheduledDowntime> >& object, const String& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (value.IsEmpty())
		return;

}

static void TIValidateScheduledDowntimeChildOptions(const intrusive_ptr<ObjectImpl<ScheduledDowntime> >& object, const Value& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (value.IsEmpty())
		return;

}

static void TIValidateScheduledDowntimeComment(const intrusive_ptr<ObjectImpl<ScheduledDowntime> >& object, const String& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (value.IsEmpty())
		return;

}

static void TIValidateScheduledDowntimeDuration(const intrusive_ptr<ObjectImpl<ScheduledDowntime> >& object, double value, std::vector<String>& location, const ValidationUtils& utils)
{
}

static void TIValidateScheduledDowntimeFixed(const intrusive_ptr<ObjectImpl<ScheduledDowntime> >& object, bool value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (!value)
		return;

}

static void TIValidateScheduledDowntimeHostName(const intrusive_ptr<ObjectImpl<ScheduledDowntime> >& object, const String& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (value.IsEmpty())
		return;

}

static void TIValidateScheduledDowntimeRanges(const intrusive_ptr<ObjectImpl<ScheduledDowntime> >& object, const Dictionary::Ptr& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (!value)
		return;

	do {
		const Dictionary::Ptr& dict = value;
		{
			ObjectLock olock(dict);
			for (const Dictionary::Pair& kv : dict) {
				const String& akey = kv.first;
				const Value& avalue = kv.second;
				location.emplace_back(akey);
				TIValidateScheduledDowntime_1(object, akey, avalue, location, utils);
				location.pop_back();
			}
		}
		return;
	} while (0);

}

static void TIValidateScheduledDowntimeServiceName(const intrusive_ptr<ObjectImpl<ScheduledDowntime> >& object, const String& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (value.IsEmpty())
		return;

}

void ObjectImpl<ScheduledDowntime>::ValidateAuthor(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateAuthor(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("author");
	TIValidateScheduledDowntimeAuthor(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<ScheduledDowntime>::ValidateChildOptions(const Lazy<Value>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateChildOptions(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("child_options");
	TIValidateScheduledDowntimeChildOptions(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<ScheduledDowntime>::ValidateComment(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateComment(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("comment");
	TIValidateScheduledDowntimeComment(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<ScheduledDowntime>::ValidateDuration(const Lazy<double>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateDuration(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("duration");
	TIValidateScheduledDowntimeDuration(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<ScheduledDowntime>::ValidateFixed(const Lazy<bool>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateFixed(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("fixed");
	TIValidateScheduledDowntimeFixed(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<ScheduledDowntime>::ValidateHostName(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateHostName(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("host_name");
	TIValidateScheduledDowntimeHostName(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<ScheduledDowntime>::ValidateRanges(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateRanges(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("ranges");
	TIValidateScheduledDowntimeRanges(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<ScheduledDowntime>::ValidateServiceName(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateServiceName(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("service_name");
	TIValidateScheduledDowntimeServiceName(this, lvalue(), location, utils);
	location.pop_back();
}

}
#pragma GCC diagnostic pop
