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

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

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

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

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

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

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

			break;
		case 101:
			if (name == "entry_type")
				return offset + 6;
			if (name == "entry_time")
				return offset + 7;
			if (name == "expire_time")
				return offset + 8;

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

			break;
		case 108:
			if (name == "legacy_id")
				return offset + 5;

			break;
		case 112:
			if (name == "persistent")
				return offset + 11;

			break;
		case 114:
			if (name == "removed_by")
				return offset + 4;
			if (name == "remove_time")
				return offset + 9;

			break;
		case 115:
			if (name == "service_name")
				return offset + 1;
			if (name == "sticky")
				return offset + 10;

			break;
		case 116:
			if (name == "text")
				return offset + 3;

			break;
	}

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

Field TypeImpl<Comment>::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", "host_name", "host", "Host", 1842, 0};
		case 1:
			return {1, "String", "service_name", "service", nullptr, 1586, 0};
		case 2:
			return {2, "String", "author", "author", nullptr, 258, 0};
		case 3:
			return {3, "String", "text", "text", nullptr, 258, 0};
		case 4:
			return {4, "String", "removed_by", "removed_by", nullptr, 3073, 0};
		case 5:
			return {5, "Number", "legacy_id", "legacy_id", nullptr, 4, 0};
		case 6:
			return {6, "Number", "entry_type", "entry_type", nullptr, 10, 0};
		case 7:
			return {7, "Timestamp", "entry_time", "entry_time", nullptr, 2, 0};
		case 8:
			return {8, "Timestamp", "expire_time", "expire_time", nullptr, 2, 0};
		case 9:
			return {9, "Timestamp", "remove_time", "remove_time", nullptr, 3073, 0};
		case 10:
			return {10, "Boolean", "sticky", "sticky", nullptr, 3074, 0};
		case 11:
			return {11, "Boolean", "persistent", "persistent", nullptr, 2, 0};
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

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

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

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

void TypeImpl<Comment>::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<Comment>::OnHostNameChanged.connect(callback);
			break;
		case 1:
			ObjectImpl<Comment>::OnServiceNameChanged.connect(callback);
			break;
		case 2:
			ObjectImpl<Comment>::OnAuthorChanged.connect(callback);
			break;
		case 3:
			ObjectImpl<Comment>::OnTextChanged.connect(callback);
			break;
		case 4:
			ObjectImpl<Comment>::OnRemovedByChanged.connect(callback);
			break;
		case 5:
			ObjectImpl<Comment>::OnLegacyIdChanged.connect(callback);
			break;
		case 6:
			ObjectImpl<Comment>::OnEntryTypeChanged.connect(callback);
			break;
		case 7:
			ObjectImpl<Comment>::OnEntryTimeChanged.connect(callback);
			break;
		case 8:
			ObjectImpl<Comment>::OnExpireTimeChanged.connect(callback);
			break;
		case 9:
			ObjectImpl<Comment>::OnRemoveTimeChanged.connect(callback);
			break;
		case 10:
			ObjectImpl<Comment>::OnStickyChanged.connect(callback);
			break;
		case 11:
			ObjectImpl<Comment>::OnPersistentChanged.connect(callback);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<Comment>::Validate(int types, const ValidationUtils& utils)
{
	ConfigObject::Validate(types, 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)
		ValidateText(Lazy<String>([this]() { return GetText(); }), utils);
	if (1 & types)
		ValidateRemovedBy(Lazy<String>([this]() { return GetRemovedBy(); }), utils);
	if (4 & types)
		ValidateLegacyId(Lazy<int>([this]() { return GetLegacyId(); }), utils);
	if (2 & types)
		ValidateEntryType(Lazy<CommentType>([this]() { return GetEntryType(); }), utils);
	if (2 & types)
		ValidateEntryTime(Lazy<Timestamp>([this]() { return GetEntryTime(); }), utils);
	if (2 & types)
		ValidateExpireTime(Lazy<Timestamp>([this]() { return GetExpireTime(); }), utils);
	if (1 & types)
		ValidateRemoveTime(Lazy<Timestamp>([this]() { return GetRemoveTime(); }), utils);
	if (2 & types)
		ValidateSticky(Lazy<bool>([this]() { return GetSticky(); }), utils);
	if (2 & types)
		ValidatePersistent(Lazy<bool>([this]() { return GetPersistent(); }), utils);
}

void ObjectImpl<Comment>::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<Comment>::SimpleValidateServiceName(const Lazy<String>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Comment>::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<Comment>::SimpleValidateText(const Lazy<String>& value, const ValidationUtils& utils)
{
	if (value().IsEmpty())
		BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "text" }, "Attribute must not be empty."));

}

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

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

void ObjectImpl<Comment>::SimpleValidateEntryType(const Lazy<CommentType>& value, const ValidationUtils& utils)
{
}

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

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

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

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

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

ObjectImpl<Comment>::ObjectImpl()
{
	SetHostName(GetDefaultHostName(), true);
	SetServiceName(GetDefaultServiceName(), true);
	SetAuthor(GetDefaultAuthor(), true);
	SetText(GetDefaultText(), true);
	SetRemovedBy(GetDefaultRemovedBy(), true);
	SetLegacyId(GetDefaultLegacyId(), true);
	SetEntryType(GetDefaultEntryType(), true);
	SetEntryTime(GetDefaultEntryTime(), true);
	SetExpireTime(GetDefaultExpireTime(), true);
	SetRemoveTime(GetDefaultRemoveTime(), true);
	SetSticky(GetDefaultSticky(), true);
	SetPersistent(GetDefaultPersistent(), true);
}

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

void ObjectImpl<Comment>::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:
			SetHostName(value, suppress_events, cookie);
			break;
		case 1:
			SetServiceName(value, suppress_events, cookie);
			break;
		case 2:
			SetAuthor(value, suppress_events, cookie);
			break;
		case 3:
			SetText(value, suppress_events, cookie);
			break;
		case 4:
			SetRemovedBy(value, suppress_events, cookie);
			break;
		case 5:
			SetLegacyId(value, suppress_events, cookie);
			break;
		case 6:
			SetEntryType(static_cast<CommentType>(static_cast<int>(value)), suppress_events, cookie);
			break;
		case 7:
			SetEntryTime(value, suppress_events, cookie);
			break;
		case 8:
			SetExpireTime(value, suppress_events, cookie);
			break;
		case 9:
			SetRemoveTime(value, suppress_events, cookie);
			break;
		case 10:
			SetSticky(value, suppress_events, cookie);
			break;
		case 11:
			SetPersistent(value, suppress_events, cookie);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

Value ObjectImpl<Comment>::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 GetHostName();
		case 1:
			return GetServiceName();
		case 2:
			return GetAuthor();
		case 3:
			return GetText();
		case 4:
			return GetRemovedBy();
		case 5:
			return GetLegacyId();
		case 6:
			return GetEntryType();
		case 7:
			return GetEntryTime();
		case 8:
			return GetExpireTime();
		case 9:
			return GetRemoveTime();
		case 10:
			return GetSticky();
		case 11:
			return GetPersistent();
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<Comment>::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:
			ValidateHostName(lvalue, utils);
			break;
		case 1:
			ValidateServiceName(lvalue, utils);
			break;
		case 2:
			ValidateAuthor(lvalue, utils);
			break;
		case 3:
			ValidateText(lvalue, utils);
			break;
		case 4:
			ValidateRemovedBy(lvalue, utils);
			break;
		case 5:
			ValidateLegacyId(lvalue, utils);
			break;
		case 6:
			ValidateEntryType(static_cast<Lazy<CommentType> >(static_cast<Lazy<int> >(lvalue)), utils);
			break;
		case 7:
			ValidateEntryTime(lvalue, utils);
			break;
		case 8:
			ValidateExpireTime(lvalue, utils);
			break;
		case 9:
			ValidateRemoveTime(lvalue, utils);
			break;
		case 10:
			ValidateSticky(lvalue, utils);
			break;
		case 11:
			ValidatePersistent(lvalue, utils);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<Comment>::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:
			NotifyHostName(cookie);
			break;
		case 1:
			NotifyServiceName(cookie);
			break;
		case 2:
			NotifyAuthor(cookie);
			break;
		case 3:
			NotifyText(cookie);
			break;
		case 4:
			NotifyRemovedBy(cookie);
			break;
		case 5:
			NotifyLegacyId(cookie);
			break;
		case 6:
			NotifyEntryType(cookie);
			break;
		case 7:
			NotifyEntryTime(cookie);
			break;
		case 8:
			NotifyExpireTime(cookie);
			break;
		case 9:
			NotifyRemoveTime(cookie);
			break;
		case 10:
			NotifySticky(cookie);
			break;
		case 11:
			NotifyPersistent(cookie);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

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

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

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

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

String ObjectImpl<Comment>::GetText() const
{
	return m_Text.load();
}

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

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

CommentType ObjectImpl<Comment>::GetEntryType() const
{
	return m_EntryType.load();
}

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

Timestamp ObjectImpl<Comment>::GetExpireTime() const
{
	return m_ExpireTime.load();
}

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

bool ObjectImpl<Comment>::GetSticky() const
{
	return m_Sticky.load();
}

bool ObjectImpl<Comment>::GetPersistent() const
{
	return m_Persistent.load();
}

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

}

void ObjectImpl<Comment>::SetText(const String& value, bool suppress_events, const Value& cookie)
{
	m_Text.store(value);
	if (!suppress_events) {
		NotifyText(cookie);
	}

}

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

}

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

}

void ObjectImpl<Comment>::SetEntryType(const CommentType& value, bool suppress_events, const Value& cookie)
{
	m_EntryType.store(value);
	if (!suppress_events) {
		NotifyEntryType(cookie);
	}

}

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

}

void ObjectImpl<Comment>::SetExpireTime(const Timestamp& value, bool suppress_events, const Value& cookie)
{
	m_ExpireTime.store(value);
	if (!suppress_events) {
		NotifyExpireTime(cookie);
	}

}

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

}

void ObjectImpl<Comment>::SetSticky(bool value, bool suppress_events, const Value& cookie)
{
	m_Sticky.store(value);
	if (!suppress_events) {
		NotifySticky(cookie);
	}

}

void ObjectImpl<Comment>::SetPersistent(bool value, bool suppress_events, const Value& cookie)
{
	m_Persistent.store(value);
	if (!suppress_events) {
		NotifyPersistent(cookie);
	}

}

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

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

			return nullptr;
		
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

String ObjectImpl<Comment>::GetDefaultText() const
{
	return String();
}

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

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

CommentType ObjectImpl<Comment>::GetDefaultEntryType() const
{
	 return CommentUser; 
}

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

Timestamp ObjectImpl<Comment>::GetDefaultExpireTime() const
{
	return Timestamp();
}

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

bool ObjectImpl<Comment>::GetDefaultSticky() const
{
	return bool();
}

bool ObjectImpl<Comment>::GetDefaultPersistent() const
{
	return bool();
}


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


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


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


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


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


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


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


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


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


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


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


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

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

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

void ObjectImpl<Comment>::ValidateEntryType(const Lazy<CommentType>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateEntryType(lvalue, utils);
}

void ObjectImpl<Comment>::ValidateExpireTime(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateExpireTime(lvalue, utils);
}

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

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

void ObjectImpl<Comment>::ValidatePersistent(const Lazy<bool>& lvalue, const ValidationUtils& utils)
{
	SimpleValidatePersistent(lvalue, utils);
}

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

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

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

void ObjectImpl<Comment>::ValidateSticky(const Lazy<bool>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateSticky(lvalue, utils);
}

void ObjectImpl<Comment>::ValidateText(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateText(lvalue, utils);
}

}
#pragma GCC diagnostic pop
