#include "duckdb/catalog/catalog_entry/schema_catalog_entry.hpp"

#include "duckdb/catalog/catalog.hpp"
#include "duckdb/common/algorithm.hpp"
#include "duckdb/common/exception.hpp"
#include "duckdb/common/field_writer.hpp"
#include "duckdb/catalog/dependency_list.hpp"
#include "duckdb/parser/parsed_data/create_schema_info.hpp"

#include <sstream>

namespace duckdb {

SchemaCatalogEntry::SchemaCatalogEntry(Catalog *catalog, string name_p, bool internal)
    : CatalogEntry(CatalogType::SCHEMA_ENTRY, catalog, std::move(name_p)) {
	this->internal = internal;
}

CatalogTransaction SchemaCatalogEntry::GetCatalogTransaction(ClientContext &context) {
	return CatalogTransaction(*catalog, context);
}

SimilarCatalogEntry SchemaCatalogEntry::GetSimilarEntry(CatalogTransaction transaction, CatalogType type,
                                                        const string &name) {
	SimilarCatalogEntry result;
	Scan(transaction.GetContext(), type, [&](CatalogEntry *entry) {
		auto ldist = StringUtil::LevenshteinDistance(entry->name, name);
		if (ldist < result.distance) {
			result.distance = ldist;
			result.name = entry->name;
		}
	});
	return result;
}

void SchemaCatalogEntry::Serialize(Serializer &serializer) {
	FieldWriter writer(serializer);
	writer.WriteString(name);
	writer.Finalize();
}

unique_ptr<CreateSchemaInfo> SchemaCatalogEntry::Deserialize(Deserializer &source) {
	auto info = make_unique<CreateSchemaInfo>();

	FieldReader reader(source);
	info->schema = reader.ReadRequired<string>();
	reader.Finalize();

	return info;
}

CatalogEntry *SchemaCatalogEntry::CreateRole(CatalogTransaction transaction, CreateRoleInfo *info){
	throw NotImplementedException("CreateFortress, Not supported for this type of Schema");
}

CatalogEntry *SchemaCatalogEntry::CreateTag(CatalogTransaction transaction, CreateTagInfo *info){
	throw NotImplementedException("CreateFortress, Not supported for this type of Schema");
}

CatalogEntry *SchemaCatalogEntry::CreateFortress(CatalogTransaction transaction, CreateFortressInfo *info){
	throw NotImplementedException("CreateFortress, Not supported for this type of Schema");
}

string SchemaCatalogEntry::ToSQL() {
	std::stringstream ss;
	ss << "CREATE SCHEMA " << name << ";";
	return ss.str();
}

} // namespace duckdb
