#ifndef IDOPGSQLCONNECTION_TI
#define IDOPGSQLCONNECTION_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 "db_ido/dbconnection.hpp"

namespace icinga
{

class IdoPgsqlConnection;

template<>
class TypeImpl<IdoPgsqlConnection> : public TypeImpl<DbConnection>
{
public:
	DECLARE_PTR_TYPEDEFS(TypeImpl<IdoPgsqlConnection>);

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

	void Validate(int types, const ValidationUtils& utils) override;
	void SimpleValidateHost(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidatePort(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateUser(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidatePassword(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateDatabase(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateInstanceName(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateInstanceDescription(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateSslMode(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateSslKey(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateSslCert(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateSslCa(const Lazy<String>& value, const ValidationUtils& utils);
public:
	ObjectImpl<IdoPgsqlConnection>();
public:
	~ObjectImpl<IdoPgsqlConnection>() 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 GetHost() const;
public:
	String GetPort() const;
public:
	String GetUser() const;
public:
	String GetPassword() const;
public:
	String GetDatabase() const;
public:
	String GetInstanceName() const;
public:
	String GetInstanceDescription() const;
public:
	String GetSslMode() const;
public:
	String GetSslKey() const;
public:
	String GetSslCert() const;
public:
	String GetSslCa() const;
public:
	void SetHost(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetPort(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetUser(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetPassword(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetDatabase(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetInstanceName(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetInstanceDescription(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetSslMode(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetSslKey(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetSslCert(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetSslCa(const String& value, bool suppress_events = false, const Value& cookie = Empty);
protected:
public:
	virtual void NotifyHost(const Value& cookie = Empty);
public:
	virtual void NotifyPort(const Value& cookie = Empty);
public:
	virtual void NotifyUser(const Value& cookie = Empty);
public:
	virtual void NotifyPassword(const Value& cookie = Empty);
public:
	virtual void NotifyDatabase(const Value& cookie = Empty);
public:
	virtual void NotifyInstanceName(const Value& cookie = Empty);
public:
	virtual void NotifyInstanceDescription(const Value& cookie = Empty);
public:
	virtual void NotifySslMode(const Value& cookie = Empty);
public:
	virtual void NotifySslKey(const Value& cookie = Empty);
public:
	virtual void NotifySslCert(const Value& cookie = Empty);
public:
	virtual void NotifySslCa(const Value& cookie = Empty);
private:
	inline String GetDefaultHost() const;
private:
	inline String GetDefaultPort() const;
private:
	inline String GetDefaultUser() const;
private:
	inline String GetDefaultPassword() const;
private:
	inline String GetDefaultDatabase() const;
private:
	inline String GetDefaultInstanceName() const;
private:
	inline String GetDefaultInstanceDescription() const;
private:
	inline String GetDefaultSslMode() const;
private:
	inline String GetDefaultSslKey() const;
private:
	inline String GetDefaultSslCert() const;
private:
	inline String GetDefaultSslCa() const;
protected:
	virtual void ValidateHost(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidatePort(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateUser(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidatePassword(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateDatabase(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateInstanceName(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateInstanceDescription(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateSslMode(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateSslKey(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateSslCert(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateSslCa(const Lazy<String>& lvalue, const ValidationUtils& utils);
private:
	AtomicOrLocked<String> m_Host;
	AtomicOrLocked<String> m_Port;
	AtomicOrLocked<String> m_User;
	AtomicOrLocked<String> m_Password;
	AtomicOrLocked<String> m_Database;
	AtomicOrLocked<String> m_InstanceName;
	AtomicOrLocked<String> m_InstanceDescription;
	AtomicOrLocked<String> m_SslMode;
	AtomicOrLocked<String> m_SslKey;
	AtomicOrLocked<String> m_SslCert;
	AtomicOrLocked<String> m_SslCa;
public:
	static boost::signals2::signal<void (const intrusive_ptr<IdoPgsqlConnection>&, const Value&)> OnHostChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IdoPgsqlConnection>&, const Value&)> OnPortChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IdoPgsqlConnection>&, const Value&)> OnUserChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IdoPgsqlConnection>&, const Value&)> OnPasswordChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IdoPgsqlConnection>&, const Value&)> OnDatabaseChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IdoPgsqlConnection>&, const Value&)> OnInstanceNameChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IdoPgsqlConnection>&, const Value&)> OnInstanceDescriptionChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IdoPgsqlConnection>&, const Value&)> OnSslModeChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IdoPgsqlConnection>&, const Value&)> OnSslKeyChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IdoPgsqlConnection>&, const Value&)> OnSslCertChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IdoPgsqlConnection>&, const Value&)> OnSslCaChanged;
};

}
#endif /* IDOPGSQLCONNECTION_TI */
