#ifndef APILISTENER_TI
#define APILISTENER_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 "remote/i2-remote.hpp"

#include "base/configobject.hpp"

#include "base/application.hpp"

#include "base/tlsutility.hpp"

namespace icinga
{

class ApiListener;

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

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

	void Validate(int types, const ValidationUtils& utils) override;
	void SimpleValidateCertPath(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateAccessControlAllowHeaders(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateAccessControlAllowMethods(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateTicketSalt(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateIdentity(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateBindPort(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateBindHost(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateTlsProtocolmin(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateCipherList(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateCrlPath(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateCaPath(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateKeyPath(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateConnectTimeout(const Lazy<double>& value, const ValidationUtils& utils);
	void SimpleValidateTlsHandshakeTimeout(const Lazy<double>& value, const ValidationUtils& utils);
	void SimpleValidateAccessControlAllowOrigin(const Lazy<Array::Ptr>& value, const ValidationUtils& utils);
	void SimpleValidateHttpResponseHeaders(const Lazy<Dictionary::Ptr>& value, const ValidationUtils& utils);
	void SimpleValidateLastFailedZonesStageValidation(const Lazy<Dictionary::Ptr>& value, const ValidationUtils& utils);
	void SimpleValidateMaxAnonymousClients(const Lazy<int>& value, const ValidationUtils& utils);
	void SimpleValidateLogMessageTimestamp(const Lazy<Timestamp>& value, const ValidationUtils& utils);
	void SimpleValidateEnforceFilterExpressionPermission(const Lazy<bool>& value, const ValidationUtils& utils);
	void SimpleValidateAccessControlAllowCredentials(const Lazy<bool>& value, const ValidationUtils& utils);
	void SimpleValidateAcceptCommands(const Lazy<bool>& value, const ValidationUtils& utils);
	void SimpleValidateAcceptConfig(const Lazy<bool>& value, const ValidationUtils& utils);
public:
	ObjectImpl<ApiListener>();
public:
	~ObjectImpl<ApiListener>() 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 GetCertPath() const;
public:
	String GetAccessControlAllowHeaders() const;
public:
	String GetAccessControlAllowMethods() const;
public:
	String GetTicketSalt() const;
public:
	String GetIdentity() const;
public:
	String GetBindPort() const;
public:
	String GetBindHost() const;
public:
	String GetTlsProtocolmin() const;
public:
	String GetCipherList() const;
public:
	String GetCrlPath() const;
public:
	String GetCaPath() const;
public:
	String GetKeyPath() const;
public:
	double GetConnectTimeout() const;
public:
	virtual double GetTlsHandshakeTimeout() const = 0;
public:
	Array::Ptr GetAccessControlAllowOrigin() const;
public:
	Dictionary::Ptr GetHttpResponseHeaders() const;
public:
	Dictionary::Ptr GetLastFailedZonesStageValidation() const;
public:
	int GetMaxAnonymousClients() const;
public:
	Timestamp GetLogMessageTimestamp() const;
public:
	bool GetEnforceFilterExpressionPermission() const;
public:
	bool GetAccessControlAllowCredentials() const;
public:
	bool GetAcceptCommands() const;
public:
	bool GetAcceptConfig() const;
public:
	void SetCertPath(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetAccessControlAllowHeaders(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetAccessControlAllowMethods(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetTicketSalt(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetIdentity(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 SetBindHost(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetTlsProtocolmin(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetCipherList(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetCrlPath(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetCaPath(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetKeyPath(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetConnectTimeout(double value, bool suppress_events = false, const Value& cookie = Empty);
public:
	virtual void SetTlsHandshakeTimeout(double value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	void SetAccessControlAllowOrigin(const Array::Ptr& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetHttpResponseHeaders(const Dictionary::Ptr& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetLastFailedZonesStageValidation(const Dictionary::Ptr& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetMaxAnonymousClients(int value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetLogMessageTimestamp(const Timestamp& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetEnforceFilterExpressionPermission(bool value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetAccessControlAllowCredentials(bool value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetAcceptCommands(bool value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetAcceptConfig(bool value, bool suppress_events = false, const Value& cookie = Empty);
protected:
public:
	virtual void NotifyCertPath(const Value& cookie = Empty);
public:
	virtual void NotifyAccessControlAllowHeaders(const Value& cookie = Empty);
public:
	virtual void NotifyAccessControlAllowMethods(const Value& cookie = Empty);
public:
	virtual void NotifyTicketSalt(const Value& cookie = Empty);
public:
	virtual void NotifyIdentity(const Value& cookie = Empty);
public:
	virtual void NotifyBindPort(const Value& cookie = Empty);
public:
	virtual void NotifyBindHost(const Value& cookie = Empty);
public:
	virtual void NotifyTlsProtocolmin(const Value& cookie = Empty);
public:
	virtual void NotifyCipherList(const Value& cookie = Empty);
public:
	virtual void NotifyCrlPath(const Value& cookie = Empty);
public:
	virtual void NotifyCaPath(const Value& cookie = Empty);
public:
	virtual void NotifyKeyPath(const Value& cookie = Empty);
public:
	virtual void NotifyConnectTimeout(const Value& cookie = Empty);
public:
	virtual void NotifyTlsHandshakeTimeout(const Value& cookie = Empty);
public:
	virtual void NotifyAccessControlAllowOrigin(const Value& cookie = Empty);
public:
	virtual void NotifyHttpResponseHeaders(const Value& cookie = Empty);
public:
	virtual void NotifyLastFailedZonesStageValidation(const Value& cookie = Empty);
public:
	virtual void NotifyMaxAnonymousClients(const Value& cookie = Empty);
public:
	virtual void NotifyLogMessageTimestamp(const Value& cookie = Empty);
public:
	virtual void NotifyEnforceFilterExpressionPermission(const Value& cookie = Empty);
public:
	virtual void NotifyAccessControlAllowCredentials(const Value& cookie = Empty);
public:
	virtual void NotifyAcceptCommands(const Value& cookie = Empty);
public:
	virtual void NotifyAcceptConfig(const Value& cookie = Empty);
private:
	inline String GetDefaultCertPath() const;
private:
	inline String GetDefaultAccessControlAllowHeaders() const;
private:
	inline String GetDefaultAccessControlAllowMethods() const;
private:
	inline String GetDefaultTicketSalt() const;
private:
	inline String GetDefaultIdentity() const;
private:
	inline String GetDefaultBindPort() const;
private:
	inline String GetDefaultBindHost() const;
private:
	inline String GetDefaultTlsProtocolmin() const;
private:
	inline String GetDefaultCipherList() const;
private:
	inline String GetDefaultCrlPath() const;
private:
	inline String GetDefaultCaPath() const;
private:
	inline String GetDefaultKeyPath() const;
private:
	inline double GetDefaultConnectTimeout() const;
private:
	inline double GetDefaultTlsHandshakeTimeout() const;
private:
	inline Array::Ptr GetDefaultAccessControlAllowOrigin() const;
private:
	inline Dictionary::Ptr GetDefaultHttpResponseHeaders() const;
private:
	inline Dictionary::Ptr GetDefaultLastFailedZonesStageValidation() const;
private:
	inline int GetDefaultMaxAnonymousClients() const;
private:
	inline Timestamp GetDefaultLogMessageTimestamp() const;
private:
	inline bool GetDefaultEnforceFilterExpressionPermission() const;
private:
	inline bool GetDefaultAccessControlAllowCredentials() const;
private:
	inline bool GetDefaultAcceptCommands() const;
private:
	inline bool GetDefaultAcceptConfig() const;
protected:
	virtual void ValidateCertPath(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateAccessControlAllowHeaders(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateAccessControlAllowMethods(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateTicketSalt(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateIdentity(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateBindPort(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateBindHost(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateTlsProtocolmin(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateCipherList(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateCrlPath(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateCaPath(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateKeyPath(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateConnectTimeout(const Lazy<double>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateTlsHandshakeTimeout(const Lazy<double>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateAccessControlAllowOrigin(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateHttpResponseHeaders(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateLastFailedZonesStageValidation(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateMaxAnonymousClients(const Lazy<int>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateLogMessageTimestamp(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateEnforceFilterExpressionPermission(const Lazy<bool>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateAccessControlAllowCredentials(const Lazy<bool>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateAcceptCommands(const Lazy<bool>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateAcceptConfig(const Lazy<bool>& lvalue, const ValidationUtils& utils);
private:
	AtomicOrLocked<String> m_CertPath;
	AtomicOrLocked<String> m_AccessControlAllowHeaders;
	AtomicOrLocked<String> m_AccessControlAllowMethods;
	AtomicOrLocked<String> m_TicketSalt;
	AtomicOrLocked<String> m_Identity;
	AtomicOrLocked<String> m_BindPort;
	AtomicOrLocked<String> m_BindHost;
	AtomicOrLocked<String> m_TlsProtocolmin;
	AtomicOrLocked<String> m_CipherList;
	AtomicOrLocked<String> m_CrlPath;
	AtomicOrLocked<String> m_CaPath;
	AtomicOrLocked<String> m_KeyPath;
	AtomicOrLocked<double> m_ConnectTimeout;
	AtomicOrLocked<Array::Ptr> m_AccessControlAllowOrigin;
	AtomicOrLocked<Dictionary::Ptr> m_HttpResponseHeaders;
	AtomicOrLocked<Dictionary::Ptr> m_LastFailedZonesStageValidation;
	AtomicOrLocked<int> m_MaxAnonymousClients;
	AtomicOrLocked<Timestamp> m_LogMessageTimestamp;
	AtomicOrLocked<bool> m_EnforceFilterExpressionPermission;
	AtomicOrLocked<bool> m_AccessControlAllowCredentials;
	AtomicOrLocked<bool> m_AcceptCommands;
	AtomicOrLocked<bool> m_AcceptConfig;
public:
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnCertPathChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnAccessControlAllowHeadersChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnAccessControlAllowMethodsChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnTicketSaltChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnIdentityChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnBindPortChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnBindHostChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnTlsProtocolminChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnCipherListChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnCrlPathChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnCaPathChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnKeyPathChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnConnectTimeoutChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnTlsHandshakeTimeoutChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnAccessControlAllowOriginChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnHttpResponseHeadersChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnLastFailedZonesStageValidationChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnMaxAnonymousClientsChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnLogMessageTimestampChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnEnforceFilterExpressionPermissionChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnAccessControlAllowCredentialsChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnAcceptCommandsChanged;
	static boost::signals2::signal<void (const intrusive_ptr<ApiListener>&, const Value&)> OnAcceptConfigChanged;
};

}
#endif /* APILISTENER_TI */
