#include "PgIndex.h"
#include "PgDatabaseCatalog.h"
#include "PgClassContainer.h"
#include "PgConstraint.h"
#include "PgConstraintContainer.h"
#include "PgAmContainer.h"
#include <QStringBuilder>

QString PgIndex::getAm() const
{
	auto&& cat = catalog();
	QString result;
	auto idxcls = cat.classes()->getByKey(oid());
	if (idxcls) {
		auto am = cat.ams()->getByKey(idxcls->am);
		if (am)
			result = am->name; // objectName();
	}
	return result;
}

QString PgIndex::createSql() const
{
    if (isSupportingIndex())
        return "-- implicitly created index";
	return definition + ";";

	//	const PgClass *table_class = catalog.classes()->getByKey(index.relid);
	//	const PgClass *index_class = catalog.classes()->getByKey(index.indexrelid);

	//	QString result;
	//	result = "CREATE ";
	//	if (index.isunique)
	//		result += "UNIQUE ";
	//	result += "INDEX "
	////			% quoteIdent(getIndexDisplayString(catalog, index.indexrelid))
	//			% quoteIdent(index_class.name)
	//			% "\n  ON " % genFQTableName(catalog, table_class);
	////			% "\n  USING " % index_class.am lookup in pg_am table
	//	return result;

	#if 0
			   + wxT("\n  USING ") + GetIndexType()
			   + wxT("\n  (");
		if (GetProcName().IsNull())
			str += GetQuotedColumns();
		else
		{
			str += GetQuotedSchemaPrefix(GetProcNamespace()) + qtIdent(GetProcName()) + wxT("(") + GetQuotedColumns() + wxT(")");
			if (!this->GetOperatorClasses().IsNull())
				str += wxT(" ") + GetOperatorClasses();
		}

		str += wxT(")");

		if (GetConnection()->BackendMinimumVersion(8, 2) && GetFillFactor().Length() > 0)
			str += wxT("\n  WITH (FILLFACTOR=") + GetFillFactor() + wxT(")");

		if (GetConnection()->BackendMinimumVersion(8, 0) && tablespace != GetDatabase()->GetDefaultTablespace())
			str += wxT("\nTABLESPACE ") + qtIdent(tablespace);

		AppendIfFilled(str, wxT("\n  WHERE "), GetConstraint());

		str += wxT(";\n");

		if (GetConnection()->BackendMinimumVersion(7, 5))
			if (GetIsClustered())
				str += wxT("ALTER TABLE ") + GetQuotedSchemaPrefix(GetIdxSchema()) + qtIdent(GetIdxTable())
					   +  wxT(" CLUSTER ON ") + qtIdent(GetName())
					   + wxT(";\n");
	#endif
}

QString PgIndex::dropSql() const
{
    if (isSupportingIndex())
        return "-- implicitly created index";

    QString result;
	result = "DROP INDEX "
			% fullyQualifiedQuotedObjectName()
			% ";";
	return result;
}

QString PgIndex::typeName() const
{
    return "INDEX";
}

bool PgIndex::isSupportingIndex() const
{
    // This function looks at the supporting index for constaints but this is not completely the
    // same thing. For example a fkey is supported by a unique constraint on the referred table but this
    // index has not been created as part of the constraint creation so it does not count.
    //
    // For now we assume that when the constraint and index are on the same table the index was created
    // implicitly.

    auto c = catalog().constraints()->getSupportedByIndex(oid());
    auto find_result = std::find_if(c.begin(), c.end(), [this] (auto && item) { return item.relid == relid; });
    return (find_result != c.end());
}
