#ifndef CHECKRESULT_TI
#define CHECKRESULT_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 <cstdint>

namespace icinga
{


/**
 * The state of a host.
 *
 * @ingroup icinga
 */
enum HostState
{
	HostUp = 0,
	HostDown = 1,
	HostPending = 99,
};

/**
 * The state of a service.
 *
 * @ingroup icinga
 */
enum ServiceState
{
	ServiceOK = 0,
	ServiceWarning = 1,
	ServiceCritical = 2,
	ServiceUnknown = 3,
	ServicePending = 99,
};

/**
 * The state type of a host or service.
 *
 * @ingroup icinga
 */
enum StateType
{
	StateTypeSoft = 0,
	StateTypeHard = 1
};

class CheckResult;

template<>
class TypeImpl<CheckResult> : public Type
{
public:
	DECLARE_PTR_TYPEDEFS(TypeImpl<CheckResult>);

	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;
	int GetActivationPriority() const override;
public:
	void RegisterAttributeHandler(int fieldId, const Type::AttributeHandler& callback) override;
};


template<>
class ObjectImpl<CheckResult> : public Object
{
public:
	DECLARE_PTR_TYPEDEFS(ObjectImpl<CheckResult>);

	void Validate(int types, const ValidationUtils& utils) override;
	void SimpleValidateCommand(const Lazy<Value>& value, const ValidationUtils& utils);
	void SimpleValidateOutput(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateCheckSource(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateSchedulingSource(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateTtl(const Lazy<double>& value, const ValidationUtils& utils);
	void SimpleValidatePerformanceData(const Lazy<Array::Ptr>& value, const ValidationUtils& utils);
	void SimpleValidateVarsBefore(const Lazy<Dictionary::Ptr>& value, const ValidationUtils& utils);
	void SimpleValidateVarsAfter(const Lazy<Dictionary::Ptr>& value, const ValidationUtils& utils);
	void SimpleValidateState(const Lazy<ServiceState>& value, const ValidationUtils& utils);
	void SimpleValidatePreviousHardState(const Lazy<ServiceState>& value, const ValidationUtils& utils);
	void SimpleValidateScheduleStart(const Lazy<Timestamp>& value, const ValidationUtils& utils);
	void SimpleValidateScheduleEnd(const Lazy<Timestamp>& value, const ValidationUtils& utils);
	void SimpleValidateExecutionStart(const Lazy<Timestamp>& value, const ValidationUtils& utils);
	void SimpleValidateExecutionEnd(const Lazy<Timestamp>& value, const ValidationUtils& utils);
	void SimpleValidateActive(const Lazy<bool>& value, const ValidationUtils& utils);
	void SimpleValidateExitStatus(const Lazy<int_fast64_t>& value, const ValidationUtils& utils);
public:
	ObjectImpl<CheckResult>();
public:
	~ObjectImpl<CheckResult>() 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:
	Value GetCommand() const;
public:
	String GetOutput() const;
public:
	String GetCheckSource() const;
public:
	String GetSchedulingSource() const;
public:
	double GetTtl() const;
public:
	Array::Ptr GetPerformanceData() const;
public:
	Dictionary::Ptr GetVarsBefore() const;
public:
	Dictionary::Ptr GetVarsAfter() const;
public:
	ServiceState GetState() const;
public:
	ServiceState GetPreviousHardState() const;
public:
	Timestamp GetScheduleStart() const;
public:
	Timestamp GetScheduleEnd() const;
public:
	Timestamp GetExecutionStart() const;
public:
	Timestamp GetExecutionEnd() const;
public:
	bool GetActive() const;
public:
	int_fast64_t GetExitStatus() const;
public:
	void SetCommand(const Value& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetOutput(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetCheckSource(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetSchedulingSource(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetTtl(double value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetPerformanceData(const Array::Ptr& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetVarsBefore(const Dictionary::Ptr& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetVarsAfter(const Dictionary::Ptr& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetState(const ServiceState& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetPreviousHardState(const ServiceState& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetScheduleStart(const Timestamp& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetScheduleEnd(const Timestamp& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetExecutionStart(const Timestamp& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetExecutionEnd(const Timestamp& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetActive(bool value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetExitStatus(const int_fast64_t& value, bool suppress_events = false, const Value& cookie = Empty);
protected:
public:
	virtual void NotifyCommand(const Value& cookie = Empty);
public:
	virtual void NotifyOutput(const Value& cookie = Empty);
public:
	virtual void NotifyCheckSource(const Value& cookie = Empty);
public:
	virtual void NotifySchedulingSource(const Value& cookie = Empty);
public:
	virtual void NotifyTtl(const Value& cookie = Empty);
public:
	virtual void NotifyPerformanceData(const Value& cookie = Empty);
public:
	virtual void NotifyVarsBefore(const Value& cookie = Empty);
public:
	virtual void NotifyVarsAfter(const Value& cookie = Empty);
public:
	virtual void NotifyState(const Value& cookie = Empty);
public:
	virtual void NotifyPreviousHardState(const Value& cookie = Empty);
public:
	virtual void NotifyScheduleStart(const Value& cookie = Empty);
public:
	virtual void NotifyScheduleEnd(const Value& cookie = Empty);
public:
	virtual void NotifyExecutionStart(const Value& cookie = Empty);
public:
	virtual void NotifyExecutionEnd(const Value& cookie = Empty);
public:
	virtual void NotifyActive(const Value& cookie = Empty);
public:
	virtual void NotifyExitStatus(const Value& cookie = Empty);
private:
	inline Value GetDefaultCommand() const;
private:
	inline String GetDefaultOutput() const;
private:
	inline String GetDefaultCheckSource() const;
private:
	inline String GetDefaultSchedulingSource() const;
private:
	inline double GetDefaultTtl() const;
private:
	inline Array::Ptr GetDefaultPerformanceData() const;
private:
	inline Dictionary::Ptr GetDefaultVarsBefore() const;
private:
	inline Dictionary::Ptr GetDefaultVarsAfter() const;
private:
	inline ServiceState GetDefaultState() const;
private:
	inline ServiceState GetDefaultPreviousHardState() const;
private:
	inline Timestamp GetDefaultScheduleStart() const;
private:
	inline Timestamp GetDefaultScheduleEnd() const;
private:
	inline Timestamp GetDefaultExecutionStart() const;
private:
	inline Timestamp GetDefaultExecutionEnd() const;
private:
	inline bool GetDefaultActive() const;
private:
	inline int_fast64_t GetDefaultExitStatus() const;
protected:
	virtual void ValidateCommand(const Lazy<Value>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateOutput(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateCheckSource(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateSchedulingSource(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateTtl(const Lazy<double>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidatePerformanceData(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateVarsBefore(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateVarsAfter(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateState(const Lazy<ServiceState>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidatePreviousHardState(const Lazy<ServiceState>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateScheduleStart(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateScheduleEnd(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateExecutionStart(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateExecutionEnd(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateActive(const Lazy<bool>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateExitStatus(const Lazy<int_fast64_t>& lvalue, const ValidationUtils& utils);
private:
	AtomicOrLocked<Value> m_Command;
	AtomicOrLocked<String> m_Output;
	AtomicOrLocked<String> m_CheckSource;
	AtomicOrLocked<String> m_SchedulingSource;
	AtomicOrLocked<double> m_Ttl;
	AtomicOrLocked<Array::Ptr> m_PerformanceData;
	AtomicOrLocked<Dictionary::Ptr> m_VarsBefore;
	AtomicOrLocked<Dictionary::Ptr> m_VarsAfter;
	AtomicOrLocked<ServiceState> m_State;
	AtomicOrLocked<ServiceState> m_PreviousHardState;
	AtomicOrLocked<Timestamp> m_ScheduleStart;
	AtomicOrLocked<Timestamp> m_ScheduleEnd;
	AtomicOrLocked<Timestamp> m_ExecutionStart;
	AtomicOrLocked<Timestamp> m_ExecutionEnd;
	AtomicOrLocked<bool> m_Active;
	AtomicOrLocked<int_fast64_t> m_ExitStatus;
public:
	static boost::signals2::signal<void (const intrusive_ptr<CheckResult>&, const Value&)> OnCommandChanged;
	static boost::signals2::signal<void (const intrusive_ptr<CheckResult>&, const Value&)> OnOutputChanged;
	static boost::signals2::signal<void (const intrusive_ptr<CheckResult>&, const Value&)> OnCheckSourceChanged;
	static boost::signals2::signal<void (const intrusive_ptr<CheckResult>&, const Value&)> OnSchedulingSourceChanged;
	static boost::signals2::signal<void (const intrusive_ptr<CheckResult>&, const Value&)> OnTtlChanged;
	static boost::signals2::signal<void (const intrusive_ptr<CheckResult>&, const Value&)> OnPerformanceDataChanged;
	static boost::signals2::signal<void (const intrusive_ptr<CheckResult>&, const Value&)> OnVarsBeforeChanged;
	static boost::signals2::signal<void (const intrusive_ptr<CheckResult>&, const Value&)> OnVarsAfterChanged;
	static boost::signals2::signal<void (const intrusive_ptr<CheckResult>&, const Value&)> OnStateChanged;
	static boost::signals2::signal<void (const intrusive_ptr<CheckResult>&, const Value&)> OnPreviousHardStateChanged;
	static boost::signals2::signal<void (const intrusive_ptr<CheckResult>&, const Value&)> OnScheduleStartChanged;
	static boost::signals2::signal<void (const intrusive_ptr<CheckResult>&, const Value&)> OnScheduleEndChanged;
	static boost::signals2::signal<void (const intrusive_ptr<CheckResult>&, const Value&)> OnExecutionStartChanged;
	static boost::signals2::signal<void (const intrusive_ptr<CheckResult>&, const Value&)> OnExecutionEndChanged;
	static boost::signals2::signal<void (const intrusive_ptr<CheckResult>&, const Value&)> OnActiveChanged;
	static boost::signals2::signal<void (const intrusive_ptr<CheckResult>&, const Value&)> OnExitStatusChanged;
};

}
#endif /* CHECKRESULT_TI */
