#include "ProcTableModel.h"
#include "catalog/PgDatabaseCatalog.h"
#include "catalog/PgProcContainer.h"
#include "catalog/PgLanguageContainer.h"
#include "catalog/PgNamespace.h"
#include "CustomDataRole.h"

ProcTableModel::ProcTableModel(QObject *parent)
	: QAbstractTableModel(parent)
{
}

QVariant ProcTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
	if (orientation == Qt::Horizontal) {
		if (role == Qt::DisplayRole) {
			switch (section) {
			case NameCol:      return tr("Name");
			case NamespaceCol: return tr("Schema");
			case OwnerCol:     return tr("Owner");
			case LangCol:      return tr("Language");
			case AclCol:       return tr("ACL");
			}
		}
	}
	return QVariant();
}

void ProcTableModel::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat)
{
	if (cat != m_catalog) {
		m_catalog = cat;
		refreshConnection = connect(m_catalog.get(), &PgDatabaseCatalog::refreshed,
										this, &ProcTableModel::refresh);
	}
	refresh();
}

void ProcTableModel::setNamespaceFilter(NamespaceFilter filter)
{
	m_namespaceFilter = filter;
	refresh();
}

void ProcTableModel::refresh()
{
	if (!m_catalog)
		return;

	beginResetModel();

	auto && procs = m_catalog->procs();
	m_procs.clear();
	for (auto&& p : *procs) {
		bool add = false;
		switch (m_namespaceFilter) {
		case NamespaceFilter::User:
			add = !p.ns().isSystemCatalog();
			break;
		case NamespaceFilter::PgCatalog:
			add = p.ns().objectName() == "pg_catalog";
			break;
		case NamespaceFilter::InformationSchema:
			add = p.ns().objectName() == "information_schema";
			break;
		}
		if (add)
			m_procs.push_back(p);
	}

	endResetModel();
}

int ProcTableModel::rowCount(const QModelIndex &) const
{
	return static_cast<int>(m_procs.size());
}

int ProcTableModel::columnCount(const QModelIndex &) const
{
	return colCount;
}

QVariant ProcTableModel::data(const QModelIndex &index, int role) const
{
	if (role == Qt::DisplayRole)
		return getData(index);
	else if (role == CustomDataTypeRole)
		return getType(index.column());
//	else if (role == FirstHiddenValue) {
//		auto&& t = m_triggers->getByIdx(index.row());
//		return t.relid; //
//	}
	return QVariant();
}

PgProc ProcTableModel::proc(int row) const
{
	return m_procs.at(static_cast<size_t>(row));
}

Oid ProcTableModel::getType(int ) const
{
//	switch (column) {
//	case NameCol:      return tr("Name");
//	case NamespaceCol: return tr("Schema");
//	case OwnerCol:     return tr("Owner");
//	case LangCol:      return tr("Language");
//			return Pgsql::bool_oid;
//	}
	return Pgsql::varchar_oid;
}

QVariant ProcTableModel::getData(const QModelIndex &index) const
{
	auto&& t = m_procs.at(static_cast<size_t>(index.row()));
	switch (index.column()) {
	case NameCol: return t.objectName();
	case NamespaceCol: return t.nsName();
	case OwnerCol: return t.ownerName();
	case LangCol: {
		auto lan = m_catalog->languages()->getByKey(t.lang);
		if (lan) return lan->objectName();
		return t.lang;
	}
	case AclCol: return t.aclString();
	}
	return QVariant();
}


