#ifndef INFLUXDBWRITER_TI
#define INFLUXDBWRITER_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 "perfdata/influxdbcommonwriter.hpp"

namespace icinga
{

class InfluxdbWriter;

template<>
class TypeImpl<InfluxdbWriter> : public TypeImpl<InfluxdbCommonWriter>
{
public:
	DECLARE_PTR_TYPEDEFS(TypeImpl<InfluxdbWriter>);

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

	void Validate(int types, const ValidationUtils& utils) override;
	void SimpleValidateDatabase(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateUsername(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidatePassword(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateBasicAuth(const Lazy<Dictionary::Ptr>& value, const ValidationUtils& utils);
public:
	ObjectImpl<InfluxdbWriter>();
public:
	~ObjectImpl<InfluxdbWriter>() 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 GetDatabase() const;
public:
	String GetUsername() const;
public:
	String GetPassword() const;
public:
	Dictionary::Ptr GetBasicAuth() const;
public:
	void SetDatabase(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetUsername(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 SetBasicAuth(const Dictionary::Ptr& value, bool suppress_events = false, const Value& cookie = Empty);
protected:
public:
	virtual void NotifyDatabase(const Value& cookie = Empty);
public:
	virtual void NotifyUsername(const Value& cookie = Empty);
public:
	virtual void NotifyPassword(const Value& cookie = Empty);
public:
	virtual void NotifyBasicAuth(const Value& cookie = Empty);
private:
	inline String GetDefaultDatabase() const;
private:
	inline String GetDefaultUsername() const;
private:
	inline String GetDefaultPassword() const;
private:
	inline Dictionary::Ptr GetDefaultBasicAuth() const;
protected:
	virtual void ValidateDatabase(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateUsername(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidatePassword(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateBasicAuth(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils);
private:
	AtomicOrLocked<String> m_Database;
	AtomicOrLocked<String> m_Username;
	AtomicOrLocked<String> m_Password;
	AtomicOrLocked<Dictionary::Ptr> m_BasicAuth;
public:
	static boost::signals2::signal<void (const intrusive_ptr<InfluxdbWriter>&, const Value&)> OnDatabaseChanged;
	static boost::signals2::signal<void (const intrusive_ptr<InfluxdbWriter>&, const Value&)> OnUsernameChanged;
	static boost::signals2::signal<void (const intrusive_ptr<InfluxdbWriter>&, const Value&)> OnPasswordChanged;
	static boost::signals2::signal<void (const intrusive_ptr<InfluxdbWriter>&, const Value&)> OnBasicAuthChanged;
};

}
#endif /* INFLUXDBWRITER_TI */
