#ifndef CONFIGURATION_TI
#define CONFIGURATION_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"

namespace icinga
{

class Configuration;

template<>
struct TypeHelper<Configuration, false>
{
	static ObjectFactory GetFactory()
	{
		return nullptr;
	}
};

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

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

	void Validate(int types, const ValidationUtils& utils) override;
	void SimpleValidatePrefixDir(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateSysconfDir(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateRunDir(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateLocalStateDir(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateZonesDir(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateVarsPath(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateStatePath(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateSpoolDir(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateRunAsUser(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateRunAsGroup(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateProgramData(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateApiBindHost(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidatePkgDataDir(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateIncludeConfDir(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateApiBindPort(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateCacheDir(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateConfigDir(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateDataDir(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateEventEngine(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidatePidPath(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateInitRunDir(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateLogDir(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateModAttrPath(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateObjectsPath(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateTlsHandshakeTimeout(const Lazy<double>& value, const ValidationUtils& utils);
	void SimpleValidateRLimitStack(const Lazy<int>& value, const ValidationUtils& utils);
	void SimpleValidateRLimitProcesses(const Lazy<int>& value, const ValidationUtils& utils);
	void SimpleValidateRLimitFiles(const Lazy<int>& value, const ValidationUtils& utils);
	void SimpleValidateConcurrency(const Lazy<int>& value, const ValidationUtils& utils);
	void SimpleValidateAttachDebugger(const Lazy<bool>& value, const ValidationUtils& utils);
public:
	ObjectImpl<Configuration>();
public:
	~ObjectImpl<Configuration>() 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:
	virtual String GetPrefixDir() const = 0;
public:
	virtual String GetSysconfDir() const = 0;
public:
	virtual String GetRunDir() const = 0;
public:
	virtual String GetLocalStateDir() const = 0;
public:
	virtual String GetZonesDir() const = 0;
public:
	virtual String GetVarsPath() const = 0;
public:
	virtual String GetStatePath() const = 0;
public:
	virtual String GetSpoolDir() const = 0;
public:
	virtual String GetRunAsUser() const = 0;
public:
	virtual String GetRunAsGroup() const = 0;
public:
	virtual String GetProgramData() const = 0;
public:
	virtual String GetApiBindHost() const = 0;
public:
	virtual String GetPkgDataDir() const = 0;
public:
	virtual String GetIncludeConfDir() const = 0;
public:
	virtual String GetApiBindPort() const = 0;
public:
	virtual String GetCacheDir() const = 0;
public:
	virtual String GetConfigDir() const = 0;
public:
	virtual String GetDataDir() const = 0;
public:
	virtual String GetEventEngine() const = 0;
public:
	virtual String GetPidPath() const = 0;
public:
	virtual String GetInitRunDir() const = 0;
public:
	virtual String GetLogDir() const = 0;
public:
	virtual String GetModAttrPath() const = 0;
public:
	virtual String GetObjectsPath() const = 0;
public:
	virtual double GetTlsHandshakeTimeout() const = 0;
public:
	virtual int GetRLimitStack() const = 0;
public:
	virtual int GetRLimitProcesses() const = 0;
public:
	virtual int GetRLimitFiles() const = 0;
public:
	virtual int GetConcurrency() const = 0;
public:
	virtual bool GetAttachDebugger() const = 0;
public:
	virtual void SetPrefixDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetSysconfDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetRunDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetLocalStateDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetZonesDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetVarsPath(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetStatePath(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetSpoolDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetRunAsUser(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetRunAsGroup(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetProgramData(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetApiBindHost(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetPkgDataDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetIncludeConfDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetApiBindPort(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetCacheDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetConfigDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetDataDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetEventEngine(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetPidPath(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetInitRunDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetLogDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetModAttrPath(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetObjectsPath(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetTlsHandshakeTimeout(double value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetRLimitStack(int value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetRLimitProcesses(int value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetRLimitFiles(int value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetConcurrency(int value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetAttachDebugger(bool value, bool suppress_events = false, const Value& cookie = Empty) = 0;
protected:
public:
	virtual void NotifyPrefixDir(const Value& cookie = Empty);
public:
	virtual void NotifySysconfDir(const Value& cookie = Empty);
public:
	virtual void NotifyRunDir(const Value& cookie = Empty);
public:
	virtual void NotifyLocalStateDir(const Value& cookie = Empty);
public:
	virtual void NotifyZonesDir(const Value& cookie = Empty);
public:
	virtual void NotifyVarsPath(const Value& cookie = Empty);
public:
	virtual void NotifyStatePath(const Value& cookie = Empty);
public:
	virtual void NotifySpoolDir(const Value& cookie = Empty);
public:
	virtual void NotifyRunAsUser(const Value& cookie = Empty);
public:
	virtual void NotifyRunAsGroup(const Value& cookie = Empty);
public:
	virtual void NotifyProgramData(const Value& cookie = Empty);
public:
	virtual void NotifyApiBindHost(const Value& cookie = Empty);
public:
	virtual void NotifyPkgDataDir(const Value& cookie = Empty);
public:
	virtual void NotifyIncludeConfDir(const Value& cookie = Empty);
public:
	virtual void NotifyApiBindPort(const Value& cookie = Empty);
public:
	virtual void NotifyCacheDir(const Value& cookie = Empty);
public:
	virtual void NotifyConfigDir(const Value& cookie = Empty);
public:
	virtual void NotifyDataDir(const Value& cookie = Empty);
public:
	virtual void NotifyEventEngine(const Value& cookie = Empty);
public:
	virtual void NotifyPidPath(const Value& cookie = Empty);
public:
	virtual void NotifyInitRunDir(const Value& cookie = Empty);
public:
	virtual void NotifyLogDir(const Value& cookie = Empty);
public:
	virtual void NotifyModAttrPath(const Value& cookie = Empty);
public:
	virtual void NotifyObjectsPath(const Value& cookie = Empty);
public:
	virtual void NotifyTlsHandshakeTimeout(const Value& cookie = Empty);
public:
	virtual void NotifyRLimitStack(const Value& cookie = Empty);
public:
	virtual void NotifyRLimitProcesses(const Value& cookie = Empty);
public:
	virtual void NotifyRLimitFiles(const Value& cookie = Empty);
public:
	virtual void NotifyConcurrency(const Value& cookie = Empty);
public:
	virtual void NotifyAttachDebugger(const Value& cookie = Empty);
private:
	inline String GetDefaultPrefixDir() const;
private:
	inline String GetDefaultSysconfDir() const;
private:
	inline String GetDefaultRunDir() const;
private:
	inline String GetDefaultLocalStateDir() const;
private:
	inline String GetDefaultZonesDir() const;
private:
	inline String GetDefaultVarsPath() const;
private:
	inline String GetDefaultStatePath() const;
private:
	inline String GetDefaultSpoolDir() const;
private:
	inline String GetDefaultRunAsUser() const;
private:
	inline String GetDefaultRunAsGroup() const;
private:
	inline String GetDefaultProgramData() const;
private:
	inline String GetDefaultApiBindHost() const;
private:
	inline String GetDefaultPkgDataDir() const;
private:
	inline String GetDefaultIncludeConfDir() const;
private:
	inline String GetDefaultApiBindPort() const;
private:
	inline String GetDefaultCacheDir() const;
private:
	inline String GetDefaultConfigDir() const;
private:
	inline String GetDefaultDataDir() const;
private:
	inline String GetDefaultEventEngine() const;
private:
	inline String GetDefaultPidPath() const;
private:
	inline String GetDefaultInitRunDir() const;
private:
	inline String GetDefaultLogDir() const;
private:
	inline String GetDefaultModAttrPath() const;
private:
	inline String GetDefaultObjectsPath() const;
private:
	inline double GetDefaultTlsHandshakeTimeout() const;
private:
	inline int GetDefaultRLimitStack() const;
private:
	inline int GetDefaultRLimitProcesses() const;
private:
	inline int GetDefaultRLimitFiles() const;
private:
	inline int GetDefaultConcurrency() const;
private:
	inline bool GetDefaultAttachDebugger() const;
protected:
	virtual void ValidatePrefixDir(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateSysconfDir(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateRunDir(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateLocalStateDir(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateZonesDir(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateVarsPath(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateStatePath(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateSpoolDir(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateRunAsUser(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateRunAsGroup(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateProgramData(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateApiBindHost(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidatePkgDataDir(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateIncludeConfDir(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateApiBindPort(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateCacheDir(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateConfigDir(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateDataDir(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateEventEngine(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidatePidPath(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateInitRunDir(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateLogDir(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateModAttrPath(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateObjectsPath(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateTlsHandshakeTimeout(const Lazy<double>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateRLimitStack(const Lazy<int>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateRLimitProcesses(const Lazy<int>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateRLimitFiles(const Lazy<int>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateConcurrency(const Lazy<int>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateAttachDebugger(const Lazy<bool>& lvalue, const ValidationUtils& utils);
private:
public:
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnPrefixDirChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnSysconfDirChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnRunDirChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnLocalStateDirChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnZonesDirChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnVarsPathChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnStatePathChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnSpoolDirChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnRunAsUserChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnRunAsGroupChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnProgramDataChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnApiBindHostChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnPkgDataDirChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnIncludeConfDirChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnApiBindPortChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnCacheDirChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnConfigDirChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnDataDirChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnEventEngineChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnPidPathChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnInitRunDirChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnLogDirChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnModAttrPathChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnObjectsPathChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnTlsHandshakeTimeoutChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnRLimitStackChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnRLimitProcessesChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnRLimitFilesChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnConcurrencyChanged;
	static boost::signals2::signal<void (const intrusive_ptr<Configuration>&, const Value&)> OnAttachDebuggerChanged;
};

}
#endif /* CONFIGURATION_TI */
