#include "PgConstraint.h"
#include "SqlFormattingUtils.h"
#include <QStringBuilder>

void operator<<(ConstraintType &s, const Pgsql::Value &v)
{
	const char *c = v.c_str();
	switch (*c) {
	case 'c':
		s = ConstraintType::Check;
		break;
	case 'f':
		s = ConstraintType::ForeignKey;
		break;
	case 'p':
		s = ConstraintType::PrimaryKey;
		break;
	case 'u':
		s = ConstraintType::Unique;
		break;
	case 't':
		s = ConstraintType::ConstraintTrigger;
		break;
	case 'x':
		s = ConstraintType::ExclusionConstraint;
		break;
    case 'n':
        s = ConstraintType::NotNull;
        break;
    default:
        s = ConstraintType::Unknown;
        break;
	}
}

QString ShortNameForConstraintType(ConstraintType ct)
{
	QString s;
	switch (ct) {
	case ConstraintType::Check:
		s = "C";
		break;
	case ConstraintType::ForeignKey:
		s = "FK";
		break;
	case ConstraintType::PrimaryKey:
		s = "PK";
		break;
	case ConstraintType::Unique:
		s = "U";
		break;
	case ConstraintType::ConstraintTrigger:
		s = "CT";
		break;
	case ConstraintType::ExclusionConstraint:
		s = "XC";
		break;
    case ConstraintType::NotNull:
        s = "NN";
        break;
    default:
		s = "?";
		break;
	}
	return s;
}

QString LongNameForConstraintType(ConstraintType ct)
{
	QString s;
	switch (ct) {
	case ConstraintType::Check:
		s = "check";
		break;
	case ConstraintType::ForeignKey:
		s = "foreign key";
		break;
	case ConstraintType::PrimaryKey:
		s = "primary key";
		break;
	case ConstraintType::Unique:
		s = "unique";
		break;
	case ConstraintType::ConstraintTrigger:
		s = "constraint trigger";
		break;
	case ConstraintType::ExclusionConstraint:
		s = "exclusion constraint";
		break;
    case ConstraintType::NotNull:
        s = "not null";
        break;
	default:
		s = "?";
		break;
	}
	return s;
}

void operator<<(ForeignKeyAction &s, const Pgsql::Value &v)
{
	const char *c = v.c_str();
	switch (*c) {
	case 'a':
		s = ForeignKeyAction::NoAction;
		break;
	case 'r':
		s = ForeignKeyAction::Restrict;
		break;
	case 'c':
		s = ForeignKeyAction::Cascade;
		break;
	case 'n':
		s = ForeignKeyAction::SetNull;
		break;
	case 'd':
		s = ForeignKeyAction::SetDefault;
		break;
	}
}

QString ForeignKeyActionToString(ForeignKeyAction fka)
{
	QString result;
	switch (fka) {
	case ForeignKeyAction::NoAction:
		result = "NO ACTION";
		break;
	case ForeignKeyAction::Restrict:
		result = "RESTRICT";
		break;
	case ForeignKeyAction::Cascade:
		result = "CASCADE";
		break;
	case ForeignKeyAction::SetNull:
		result = "SET NULL";
		break;
	case ForeignKeyAction::SetDefault:
		result = "SET DEFAULT";
		break;
	}

	return result;
}

void operator<<(ForeignKeyMatch &s, const Pgsql::Value &v)
{
	const char *c = v.c_str();
	switch (*c) {
	case 'f':
		s = ForeignKeyMatch::Full;
		break;
	case 'p':
		s = ForeignKeyMatch::Partial;
		break;
	case 's':
		s = ForeignKeyMatch::Simple;
		break;
	}
}

QString ForeignKeyMatchToString(ForeignKeyMatch fkm)
{
	QString result;
	switch (fkm) {
	case ForeignKeyMatch::Full :
		result = "FULL";
		break;
	case ForeignKeyMatch::Partial:
		result = "PARTIAL";
		break;
	case ForeignKeyMatch::Simple:
		result = "SIMPLE";
		break;
	}
	return result;
}


//PgConstraint::PgConstraint()
//{

//}

QString PgConstraint::typeName() const
{
	return "CONSTRAINT";
}

QString PgConstraint::dropSql() const
{
    if (isInherited())
        return "-- " % objectName() % " is inherited";

    return getDropConstraintDefinition(catalog(), *this);
}

QString PgConstraint::createSql() const
{
    if (isInherited())
        return "-- " % objectName() % " is inherited";

    return getAlterTableConstraintDefinition(catalog(), *this);
}
