#ifndef LIVESTATUSLISTENER_TI
#define LIVESTATUSLISTENER_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/application.hpp"

namespace icinga
{

class LivestatusListener;

template<>
class TypeImpl<LivestatusListener> : public TypeImpl<ConfigObject>
{
public:
	DECLARE_PTR_TYPEDEFS(TypeImpl<LivestatusListener>);

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

	void Validate(int types, const ValidationUtils& utils) override;
	void SimpleValidateSocketType(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateSocketPath(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateBindHost(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateBindPort(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateCompatLogPath(const Lazy<String>& value, const ValidationUtils& utils);
public:
	ObjectImpl<LivestatusListener>();
public:
	~ObjectImpl<LivestatusListener>() 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 GetSocketType() const;
public:
	String GetSocketPath() const;
public:
	String GetBindHost() const;
public:
	String GetBindPort() const;
public:
	String GetCompatLogPath() const;
public:
	void SetSocketType(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetSocketPath(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetBindHost(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetBindPort(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetCompatLogPath(const String& value, bool suppress_events = false, const Value& cookie = Empty);
protected:
public:
	virtual void NotifySocketType(const Value& cookie = Empty);
public:
	virtual void NotifySocketPath(const Value& cookie = Empty);
public:
	virtual void NotifyBindHost(const Value& cookie = Empty);
public:
	virtual void NotifyBindPort(const Value& cookie = Empty);
public:
	virtual void NotifyCompatLogPath(const Value& cookie = Empty);
private:
	inline String GetDefaultSocketType() const;
private:
	inline String GetDefaultSocketPath() const;
private:
	inline String GetDefaultBindHost() const;
private:
	inline String GetDefaultBindPort() const;
private:
	inline String GetDefaultCompatLogPath() const;
protected:
	virtual void ValidateSocketType(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateSocketPath(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateBindHost(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateBindPort(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateCompatLogPath(const Lazy<String>& lvalue, const ValidationUtils& utils);
private:
	AtomicOrLocked<String> m_SocketType;
	AtomicOrLocked<String> m_SocketPath;
	AtomicOrLocked<String> m_BindHost;
	AtomicOrLocked<String> m_BindPort;
	AtomicOrLocked<String> m_CompatLogPath;
public:
	static boost::signals2::signal<void (const intrusive_ptr<LivestatusListener>&, const Value&)> OnSocketTypeChanged;
	static boost::signals2::signal<void (const intrusive_ptr<LivestatusListener>&, const Value&)> OnSocketPathChanged;
	static boost::signals2::signal<void (const intrusive_ptr<LivestatusListener>&, const Value&)> OnBindHostChanged;
	static boost::signals2::signal<void (const intrusive_ptr<LivestatusListener>&, const Value&)> OnBindPortChanged;
	static boost::signals2::signal<void (const intrusive_ptr<LivestatusListener>&, const Value&)> OnCompatLogPathChanged;
};

}
#endif /* LIVESTATUSLISTENER_TI */
