#ifndef DOWNTIME_TI
#define DOWNTIME_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 "base/configobject.hpp"

#include "base/utility.hpp"

namespace icinga
{


class DowntimeNameComposer : 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 Downtime;

template<>
class TypeImpl<Downtime> : public TypeImpl<ConfigObject>, public DowntimeNameComposer
{
public:
	DECLARE_PTR_TYPEDEFS(TypeImpl<Downtime>);

	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<Downtime> : public ConfigObject
{
public:
	DECLARE_PTR_TYPEDEFS(ObjectImpl<Downtime>);

	void Validate(int types, const ValidationUtils& utils) override;
	void SimpleValidateTriggeredBy(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateRemovedBy(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateAuthoritativeZone(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateConfigOwnerHash(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateConfigOwner(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateParent(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateScheduledBy(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateHostName(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateComment(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateAuthor(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateServiceName(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateTriggers(const Lazy<Array::Ptr>& value, const ValidationUtils& utils);
	void SimpleValidateLegacyId(const Lazy<int>& value, const ValidationUtils& utils);
	void SimpleValidateDuration(const Lazy<Timestamp>& value, const ValidationUtils& utils);
	void SimpleValidateTriggerTime(const Lazy<Timestamp>& value, const ValidationUtils& utils);
	void SimpleValidateEndTime(const Lazy<Timestamp>& value, const ValidationUtils& utils);
	void SimpleValidateStartTime(const Lazy<Timestamp>& value, const ValidationUtils& utils);
	void SimpleValidateRemoveTime(const Lazy<Timestamp>& value, const ValidationUtils& utils);
	void SimpleValidateEntryTime(const Lazy<Timestamp>& value, const ValidationUtils& utils);
	void SimpleValidateFixed(const Lazy<bool>& value, const ValidationUtils& utils);
	void SimpleValidateWasCancelled(const Lazy<bool>& value, const ValidationUtils& utils);
public:
	ObjectImpl<Downtime>();
public:
	~ObjectImpl<Downtime>() 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;
public:
	String GetTriggeredBy() const;
public:
	String GetRemovedBy() const;
public:
	String GetAuthoritativeZone() const;
public:
	String GetConfigOwnerHash() const;
public:
	String GetConfigOwner() const;
public:
	String GetParent() const;
public:
	String GetScheduledBy() const;
public:
	String GetHostName() const;
public:
	String GetComment() const;
public:
	String GetAuthor() const;
public:
	String GetServiceName() const;
public:
	Array::Ptr GetTriggers() const;
public:
	int GetLegacyId() const;
public:
	Timestamp GetDuration() const;
public:
	Timestamp GetTriggerTime() const;
public:
	Timestamp GetEndTime() const;
public:
	Timestamp GetStartTime() const;
public:
	Timestamp GetRemoveTime() const;
public:
	Timestamp GetEntryTime() const;
public:
	bool GetFixed() const;
public:
	bool GetWasCancelled() const;
public:
	void SetTriggeredBy(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetRemovedBy(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetAuthoritativeZone(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetConfigOwnerHash(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetConfigOwner(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetParent(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetScheduledBy(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetHostName(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetComment(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetAuthor(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetServiceName(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetTriggers(const Array::Ptr& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetLegacyId(int value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetDuration(const Timestamp& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetTriggerTime(const Timestamp& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetEndTime(const Timestamp& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetStartTime(const Timestamp& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetRemoveTime(const Timestamp& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetEntryTime(const Timestamp& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetFixed(bool value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetWasCancelled(bool value, bool suppress_events = false, const Value& cookie = Empty);
protected:
	void TrackHostName(const String& oldValue, const String& newValue);
	void TrackServiceName(const String& oldValue, const String& newValue);
public:
	Object::Ptr NavigateHostName() const;
public:
	Object::Ptr NavigateServiceName() const;
protected:
	void Start(bool runtimeCreated = false) override;
	void Stop(bool runtimeRemoved = false) override;
public:
	virtual void NotifyTriggeredBy(const Value& cookie = Empty);
public:
	virtual void NotifyRemovedBy(const Value& cookie = Empty);
public:
	virtual void NotifyAuthoritativeZone(const Value& cookie = Empty);
public:
	virtual void NotifyConfigOwnerHash(const Value& cookie = Empty);
public:
	virtual void NotifyConfigOwner(const Value& cookie = Empty);
public:
	virtual void NotifyParent(const Value& cookie = Empty);
public:
	virtual void NotifyScheduledBy(const Value& cookie = Empty);
public:
	virtual void NotifyHostName(const Value& cookie = Empty);
public:
	virtual void NotifyComment(const Value& cookie = Empty);
public:
	virtual void NotifyAuthor(const Value& cookie = Empty);
public:
	virtual void NotifyServiceName(const Value& cookie = Empty);
public:
	virtual void NotifyTriggers(const Value& cookie = Empty);
public:
	virtual void NotifyLegacyId(const Value& cookie = Empty);
public:
	virtual void NotifyDuration(const Value& cookie = Empty);
public:
	virtual void NotifyTriggerTime(const Value& cookie = Empty);
public:
	virtual void NotifyEndTime(const Value& cookie = Empty);
public:
	virtual void NotifyStartTime(const Value& cookie = Empty);
public:
	virtual void NotifyRemoveTime(const Value& cookie = Empty);
public:
	virtual void NotifyEntryTime(const Value& cookie = Empty);
public:
	virtual void NotifyFixed(const Value& cookie = Empty);
public:
	virtual void NotifyWasCancelled(const Value& cookie = Empty);
private:
	inline String GetDefaultTriggeredBy() const;
private:
	inline String GetDefaultRemovedBy() const;
private:
	inline String GetDefaultAuthoritativeZone() const;
private:
	inline String GetDefaultConfigOwnerHash() const;
private:
	inline String GetDefaultConfigOwner() const;
private:
	inline String GetDefaultParent() const;
private:
	inline String GetDefaultScheduledBy() const;
private:
	inline String GetDefaultHostName() const;
private:
	inline String GetDefaultComment() const;
private:
	inline String GetDefaultAuthor() const;
private:
	inline String GetDefaultServiceName() const;
private:
	inline Array::Ptr GetDefaultTriggers() const;
private:
	inline int GetDefaultLegacyId() const;
private:
	inline Timestamp GetDefaultDuration() const;
private:
	inline Timestamp GetDefaultTriggerTime() const;
private:
	inline Timestamp GetDefaultEndTime() const;
private:
	inline Timestamp GetDefaultStartTime() const;
private:
	inline Timestamp GetDefaultRemoveTime() const;
private:
	inline Timestamp GetDefaultEntryTime() const;
private:
	inline bool GetDefaultFixed() const;
private:
	inline bool GetDefaultWasCancelled() const;
protected:
	virtual void ValidateTriggeredBy(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateRemovedBy(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateAuthoritativeZone(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateConfigOwnerHash(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateConfigOwner(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateParent(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateScheduledBy(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateHostName(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateComment(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateAuthor(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateServiceName(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateTriggers(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateLegacyId(const Lazy<int>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateDuration(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateTriggerTime(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateEndTime(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateStartTime(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateRemoveTime(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateEntryTime(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateFixed(const Lazy<bool>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateWasCancelled(const Lazy<bool>& lvalue, const ValidationUtils& utils);
private:
	AtomicOrLocked<String> m_TriggeredBy;
	AtomicOrLocked<String> m_RemovedBy;
	AtomicOrLocked<String> m_AuthoritativeZone;
	AtomicOrLocked<String> m_ConfigOwnerHash;
	AtomicOrLocked<String> m_ConfigOwner;
	AtomicOrLocked<String> m_Parent;
	AtomicOrLocked<String> m_ScheduledBy;
	AtomicOrLocked<String> m_HostName;
	AtomicOrLocked<String> m_Comment;
	AtomicOrLocked<String> m_Author;
	AtomicOrLocked<String> m_ServiceName;
	AtomicOrLocked<Array::Ptr> m_Triggers;
	AtomicOrLocked<int> m_LegacyId;
	AtomicOrLocked<Timestamp> m_Duration;
	AtomicOrLocked<Timestamp> m_TriggerTime;
	AtomicOrLocked<Timestamp> m_EndTime;
	AtomicOrLocked<Timestamp> m_StartTime;
	AtomicOrLocked<Timestamp> m_RemoveTime;
	AtomicOrLocked<Timestamp> m_EntryTime;
	AtomicOrLocked<bool> m_Fixed;
public:
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnTriggeredByChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnRemovedByChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnAuthoritativeZoneChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnConfigOwnerHashChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnConfigOwnerChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnParentChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnScheduledByChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnHostNameChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnCommentChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnAuthorChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnServiceNameChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnTriggersChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnLegacyIdChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnDurationChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnTriggerTimeChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnEndTimeChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnStartTimeChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnRemoveTimeChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnEntryTimeChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnFixedChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Downtime>&, const Value&)> OnWasCancelledChanged;
	friend class DowntimeNameComposer;
};

}
#endif /* DOWNTIME_TI */
