#ifndef DATABASESTABLEMODEL_H
#define DATABASESTABLEMODEL_H

#include "BaseTableModel.h"
#include "catalog/PgDatabase.h"
#include <memory>

class OpenDatabase;
class PgDatabaseCatalog;

/** Class for displaying the list of databases of a server in a QTableView
 *
 */
class DatabasesTableModel : public BaseTableModel
{
	Q_OBJECT

public:
    using RowItem = PgDatabase;

	enum e_Columns : int { NameCol, DbaCol, EncodingCol, CollateCol,
						 CTypeCol, IsTemplateCol, AllowConnCol, ConnLimitCol,
                         TablespaceCol, CommentCol, SizeCol, AclCol, COL_COUNT };



    explicit DatabasesTableModel(std::shared_ptr<OpenDatabase> opendatabase, QObject *parent);

	void setDatabaseList(std::shared_ptr<const PgDatabaseCatalog> cat);

	// Header:
	QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;

	// Basic functionality:
	int rowCount(const QModelIndex &parent = QModelIndex()) const override;
	int columnCount(const QModelIndex &parent = QModelIndex()) const override;

	virtual Oid getType(int column) const override;
	virtual QVariant getData(const QModelIndex &index) const override;

    RowItem rowItem(const QModelIndex &index) const
    {
        return databases.at(index.row()).database;
    }
protected:
    virtual QVariant getDataMeaning(const QModelIndex &index) const override;
private:
    class DatabaseSize {
    public:
        Oid oid;
        int64_t totalBytes;

        DatabaseSize()
            : oid(InvalidOid)
            , totalBytes(-1)
        {}
    };
    using DatabaseSizes = std::vector<DatabaseSize>;

    class Database {
    public:
        PgDatabase database;
        DatabaseSize size;

        Database(const PgDatabase &db)
            : database(db)
        {}
    };
    using Databases = std::vector<Database>;

    std::shared_ptr<OpenDatabase> openDatabase;
	std::shared_ptr<const PgDatabaseCatalog> m_catalog;
    Databases databases;

    void StartLoadDatabaseSizes(std::map<Oid, int> oidIndex);
    DatabaseSizes QueryDatabaseSizes();
    void PopulateSizes(std::map<Oid, int> oidIndex, DatabaseSizes sizes);
};

#endif // DATABASESTABLEMODEL_H
