#ifndef TYPEMAPPINGS_H
#define TYPEMAPPINGS_H

#include <Pgsql_declare.h>
#include <QString>
#include <initializer_list>
#include <memory>
#include <unordered_map>

class PgTypeContainer;

class TypeMappingResult {
public:
	TypeMappingResult(QString codetype, QString dbtype)
		: m_codeType(codetype)
		, m_dbType(dbtype)
	{}

	const QString& codeType() const { return m_codeType; }
	const QString& dbType() const { return m_dbType; }
private:
	QString m_codeType;
	QString m_dbType;
};

class TypeMappings {
public:
	using TypeMap = std::unordered_map<Oid, QString>;
	using Mapping = std::pair<Oid, QString>;

	TypeMappings(std::shared_ptr<const PgTypeContainer> types = nullptr);

	TypeMappings(std::shared_ptr<const PgTypeContainer> types, std::initializer_list<Mapping> mappings);

	TypeMappingResult getTypeForOid(Oid oid) const;

	const TypeMap& typeMap() const { return m_typeMap; }

	QString defaultStringType() const { return m_defaultStringType; }

	void setTypes(std::shared_ptr<const PgTypeContainer> types);

	void setDefaultStringType(QString str);

	void setDefaultContainerType(QString str);

	void set(Oid oid, QString type);
	/** Removing a type from the mapping will reeastablish its default mapping
	 * which in most cases is the default string type for the language.
	 */
	void remove(Oid oid);
private:

	TypeMap m_typeMap;
	QString m_defaultStringType;
	QString m_defaultContainerType; ///< This string should contain a format variable where the element type should go

	std::shared_ptr<const PgTypeContainer> m_types;
};

#endif // TYPEMAPPINGS_H
