#pragma once

#include "table.h"
#include "relation.h"
#include <maps/wikimap/mapspro/tools/ymapsdf-conversion/json2ymapsdf/lib/common/params.h>

#include <maps/libs/json/include/builder.h>

#include <map>
#include <vector>
#include <list>
#include <string>

namespace maps::wiki::json2ymapsdf::ymapsdf::schema {

class Schema;
using SchemaPtr = std::unique_ptr<Schema>;
using Schemas = std::vector<SchemaPtr>;

class Schema {
public:
    Schema(const std::string& name, const std::string& connStr, const std::string& schemaSql);
    Schema(Schema&&) = delete;

    const std::string& name() const { return name_; }

    const Table& table(const std::string& tableName) const;
    Table* tablePtr(const std::string& tableName) const;
    bool hasTable(const std::string& tableName) const;

    const Relations& relations() const { return relations_; }

    void serialize(json::ObjectBuilder& builder) const;

    const std::string& schemaSql() const { return schemaSql_; }

private:
    std::string name_;
    std::string schemaSql_;
    std::map<std::string, std::shared_ptr<Table>> tables_;
    Relations relations_;

private:
    Table& initTable(const std::string& tableName);
    void initTables(const std::string& connStr);
    void initRelations();
};

/// Creates a new schema, constructs a view for it and drops indexes and constraints.
SchemaPtr createSchema(const Params& params);

std::string createRegionView(const Params& params, const Region& region);

} // namespace maps::wiki::json2ymapsdf::ymapsdf::schema
