#ifndef NOTIFICATION_TI
#define NOTIFICATION_TI

#include "base/object.hpp"
#include "base/type.hpp"
#include "base/value.hpp"
#include "base/array.hpp"
#include "base/atomic.hpp"
#include "base/dictionary.hpp"
#include <boost/signals2.hpp>

#include "icinga/customvarobject.hpp"

namespace icinga
{


class NotificationNameComposer : public NameComposer
{
public:
	virtual String MakeName(const String& shortName, const Object::Ptr& context) const override;
	virtual Dictionary::Ptr ParseName(const String& name) const override;
};

class Notification;

template<>
class TypeImpl<Notification> : public TypeImpl<CustomVarObject>, public NotificationNameComposer
{
public:
	DECLARE_PTR_TYPEDEFS(TypeImpl<Notification>);

	TypeImpl();
	~TypeImpl() override;

	String GetName() const override;
	int GetAttributes() const override;
	Type::Ptr GetBaseType() const override;
	int GetFieldId(const String& name) const override;
	Field GetFieldInfo(int id) const override;
	int GetFieldCount() const override;
	ObjectFactory GetFactory() const override;
	const std::unordered_set<Type*>& GetLoadDependencies() const override;
	int GetActivationPriority() const override;
public:
	void RegisterAttributeHandler(int fieldId, const Type::AttributeHandler& callback) override;
};


template<>
class ObjectImpl<Notification> : public CustomVarObject
{
public:
	DECLARE_PTR_TYPEDEFS(ObjectImpl<Notification>);

	void Validate(int types, const ValidationUtils& utils) override;
	void SimpleValidateServiceName(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateCommandEndpointRaw(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateCommandRaw(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateHostName(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidatePeriodRaw(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateInterval(const Lazy<double>& value, const ValidationUtils& utils);
	void SimpleValidateUsersRaw(const Lazy<Array::Ptr>& avalue, const ValidationUtils& utils);
	void SimpleValidateUserGroupsRaw(const Lazy<Array::Ptr>& avalue, const ValidationUtils& utils);
	void SimpleValidateTypes(const Lazy<Array::Ptr>& avalue, const ValidationUtils& utils);
	void SimpleValidateStashedNotifications(const Lazy<Array::Ptr>& value, const ValidationUtils& utils);
	void SimpleValidateStates(const Lazy<Array::Ptr>& avalue, const ValidationUtils& utils);
	void SimpleValidateNotifiedProblemUsers(const Lazy<Array::Ptr>& value, const ValidationUtils& utils);
	void SimpleValidateLastNotifiedStatePerUser(const Lazy<Dictionary::Ptr>& value, const ValidationUtils& utils);
	void SimpleValidateTimes(const Lazy<Dictionary::Ptr>& value, const ValidationUtils& utils);
	void SimpleValidateStateFilter(const Lazy<int>& value, const ValidationUtils& utils);
	void SimpleValidateTypeFilter(const Lazy<int>& value, const ValidationUtils& utils);
	void SimpleValidateNotificationNumber(const Lazy<int>& value, const ValidationUtils& utils);
	void SimpleValidateSuppressedNotifications(const Lazy<int>& value, const ValidationUtils& utils);
	void SimpleValidateLastNotification(const Lazy<Timestamp>& value, const ValidationUtils& utils);
	void SimpleValidateNextNotification(const Lazy<Timestamp>& value, const ValidationUtils& utils);
	void SimpleValidateLastProblemNotification(const Lazy<Timestamp>& value, const ValidationUtils& utils);
	void SimpleValidateNoMoreNotifications(const Lazy<bool>& value, const ValidationUtils& utils);
public:
	ObjectImpl<Notification>();
public:
	~ObjectImpl<Notification>() override;
public:
	void SetField(int id, const Value& value, bool suppress_events = false, const Value& cookie = Empty) override;
public:
	Value GetField(int id) const override;
public:
	void ValidateField(int id, const Lazy<Value>& lvalue, const ValidationUtils& utils) override;
public:
	void NotifyField(int id, const Value& cookie = Empty) override;
public:
	Object::Ptr NavigateField(int id) const override;
protected:
	String GetServiceName() const;
public:
	String GetCommandEndpointRaw() const;
protected:
	String GetCommandRaw() const;
protected:
	String GetHostName() const;
public:
	String GetPeriodRaw() const;
public:
	double GetInterval() const;
public:
	Array::Ptr GetUsersRaw() const;
public:
	Array::Ptr GetUserGroupsRaw() const;
public:
	virtual Array::Ptr GetTypes() const = 0;
public:
	Array::Ptr GetStashedNotifications() const;
public:
	virtual Array::Ptr GetStates() const = 0;
public:
	Array::Ptr GetNotifiedProblemUsers() const;
public:
	Dictionary::Ptr GetLastNotifiedStatePerUser() const;
public:
	Dictionary::Ptr GetTimes() const;
public:
	int GetStateFilter() const;
public:
	int GetTypeFilter() const;
public:
	int GetNotificationNumber() const;
public:
	int GetSuppressedNotifications() const;
public:
	Timestamp GetLastNotification() const;
public:
	Timestamp GetNextNotification() const;
public:
	Timestamp GetLastProblemNotification() const;
public:
	bool GetNoMoreNotifications() const;
protected:
	void SetServiceName(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetCommandEndpointRaw(const String& value, bool suppress_events = false, const Value& cookie = Empty);
protected:
	void SetCommandRaw(const String& value, bool suppress_events = false, const Value& cookie = Empty);
protected:
	void SetHostName(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetPeriodRaw(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetInterval(double value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetUsersRaw(const Array::Ptr& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetUserGroupsRaw(const Array::Ptr& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	virtual void SetTypes(const Array::Ptr& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	void SetStashedNotifications(const Array::Ptr& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	virtual void SetStates(const Array::Ptr& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	void SetNotifiedProblemUsers(const Array::Ptr& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetLastNotifiedStatePerUser(const Dictionary::Ptr& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetTimes(const Dictionary::Ptr& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetStateFilter(int value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetTypeFilter(int value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetNotificationNumber(int value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetSuppressedNotifications(int value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetLastNotification(const Timestamp& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetNextNotification(const Timestamp& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetLastProblemNotification(const Timestamp& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetNoMoreNotifications(bool value, bool suppress_events = false, const Value& cookie = Empty);
protected:
	void TrackServiceName(const String& oldValue, const String& newValue);
	void TrackCommandEndpointRaw(const String& oldValue, const String& newValue);
	void TrackCommandRaw(const String& oldValue, const String& newValue);
	void TrackHostName(const String& oldValue, const String& newValue);
	void TrackPeriodRaw(const String& oldValue, const String& newValue);
	void TrackUsersRaw(const Array::Ptr& oldValue, const Array::Ptr& newValue);
	void TrackUserGroupsRaw(const Array::Ptr& oldValue, const Array::Ptr& newValue);
public:
	Object::Ptr NavigateServiceName() const;
public:
	Object::Ptr NavigateCommandEndpointRaw() const;
public:
	Object::Ptr NavigateCommandRaw() const;
public:
	Object::Ptr NavigateHostName() const;
public:
	Object::Ptr NavigatePeriodRaw() const;
protected:
	void Start(bool runtimeCreated = false) override;
	void Stop(bool runtimeRemoved = false) override;
protected:
	virtual void NotifyServiceName(const Value& cookie = Empty);
public:
	virtual void NotifyCommandEndpointRaw(const Value& cookie = Empty);
protected:
	virtual void NotifyCommandRaw(const Value& cookie = Empty);
protected:
	virtual void NotifyHostName(const Value& cookie = Empty);
public:
	virtual void NotifyPeriodRaw(const Value& cookie = Empty);
public:
	virtual void NotifyInterval(const Value& cookie = Empty);
public:
	virtual void NotifyUsersRaw(const Value& cookie = Empty);
public:
	virtual void NotifyUserGroupsRaw(const Value& cookie = Empty);
public:
	virtual void NotifyTypes(const Value& cookie = Empty);
public:
	virtual void NotifyStashedNotifications(const Value& cookie = Empty);
public:
	virtual void NotifyStates(const Value& cookie = Empty);
public:
	virtual void NotifyNotifiedProblemUsers(const Value& cookie = Empty);
public:
	virtual void NotifyLastNotifiedStatePerUser(const Value& cookie = Empty);
public:
	virtual void NotifyTimes(const Value& cookie = Empty);
public:
	virtual void NotifyStateFilter(const Value& cookie = Empty);
public:
	virtual void NotifyTypeFilter(const Value& cookie = Empty);
public:
	virtual void NotifyNotificationNumber(const Value& cookie = Empty);
public:
	virtual void NotifySuppressedNotifications(const Value& cookie = Empty);
public:
	virtual void NotifyLastNotification(const Value& cookie = Empty);
public:
	virtual void NotifyNextNotification(const Value& cookie = Empty);
public:
	virtual void NotifyLastProblemNotification(const Value& cookie = Empty);
public:
	virtual void NotifyNoMoreNotifications(const Value& cookie = Empty);
private:
	inline String GetDefaultServiceName() const;
private:
	inline String GetDefaultCommandEndpointRaw() const;
private:
	inline String GetDefaultCommandRaw() const;
private:
	inline String GetDefaultHostName() const;
private:
	inline String GetDefaultPeriodRaw() const;
private:
	inline double GetDefaultInterval() const;
private:
	inline Array::Ptr GetDefaultUsersRaw() const;
private:
	inline Array::Ptr GetDefaultUserGroupsRaw() const;
private:
	inline Array::Ptr GetDefaultTypes() const;
private:
	inline Array::Ptr GetDefaultStashedNotifications() const;
private:
	inline Array::Ptr GetDefaultStates() const;
private:
	inline Array::Ptr GetDefaultNotifiedProblemUsers() const;
private:
	inline Dictionary::Ptr GetDefaultLastNotifiedStatePerUser() const;
private:
	inline Dictionary::Ptr GetDefaultTimes() const;
private:
	inline int GetDefaultStateFilter() const;
private:
	inline int GetDefaultTypeFilter() const;
private:
	inline int GetDefaultNotificationNumber() const;
private:
	inline int GetDefaultSuppressedNotifications() const;
private:
	inline Timestamp GetDefaultLastNotification() const;
private:
	inline Timestamp GetDefaultNextNotification() const;
private:
	inline Timestamp GetDefaultLastProblemNotification() const;
private:
	inline bool GetDefaultNoMoreNotifications() const;
protected:
	virtual void ValidateServiceName(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateCommandEndpointRaw(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateCommandRaw(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateHostName(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidatePeriodRaw(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateInterval(const Lazy<double>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateUsersRaw(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateUserGroupsRaw(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateTypes(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateStashedNotifications(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateStates(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateNotifiedProblemUsers(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateLastNotifiedStatePerUser(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateTimes(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateStateFilter(const Lazy<int>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateTypeFilter(const Lazy<int>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateNotificationNumber(const Lazy<int>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateSuppressedNotifications(const Lazy<int>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateLastNotification(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateNextNotification(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateLastProblemNotification(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateNoMoreNotifications(const Lazy<bool>& lvalue, const ValidationUtils& utils);
private:
	AtomicOrLocked<String> m_ServiceName;
	AtomicOrLocked<String> m_CommandEndpointRaw;
	AtomicOrLocked<String> m_CommandRaw;
	AtomicOrLocked<String> m_HostName;
	AtomicOrLocked<String> m_PeriodRaw;
	AtomicOrLocked<double> m_Interval;
	AtomicOrLocked<Array::Ptr> m_UsersRaw;
	AtomicOrLocked<Array::Ptr> m_UserGroupsRaw;
	AtomicOrLocked<Array::Ptr> m_StashedNotifications;
	AtomicOrLocked<Array::Ptr> m_NotifiedProblemUsers;
	AtomicOrLocked<Dictionary::Ptr> m_LastNotifiedStatePerUser;
	AtomicOrLocked<Dictionary::Ptr> m_Times;
	AtomicOrLocked<int> m_StateFilter;
	AtomicOrLocked<int> m_TypeFilter;
	AtomicOrLocked<int> m_NotificationNumber;
	AtomicOrLocked<int> m_SuppressedNotifications;
	AtomicOrLocked<Timestamp> m_LastNotification;
	AtomicOrLocked<Timestamp> m_NextNotification;
	AtomicOrLocked<Timestamp> m_LastProblemNotification;
	AtomicOrLocked<bool> m_NoMoreNotifications;
public:
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnServiceNameChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnCommandEndpointRawChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnCommandRawChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnHostNameChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnPeriodRawChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnIntervalChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnUsersRawChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&, const Value&)> OnUsersRawChangedWithOldValue;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnUserGroupsRawChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&, const Value&)> OnUserGroupsRawChangedWithOldValue;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnTypesChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnStashedNotificationsChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnStatesChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnNotifiedProblemUsersChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnLastNotifiedStatePerUserChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnTimesChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnStateFilterChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnTypeFilterChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnNotificationNumberChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnSuppressedNotificationsChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnLastNotificationChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnNextNotificationChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnLastProblemNotificationChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> OnNoMoreNotificationsChanged;
	friend class NotificationNameComposer;
};

}
#endif /* NOTIFICATION_TI */
