#pragma once

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

#include <pqxx/pqxx>

namespace maps {

void dumpGeometry(
    json::ObjectBuilder& builder,
    const pqxx::row& tuple,
    const std::string& shapeName = std::string());

bool dumpOptionalGeometry(
    json::ObjectBuilder& builder,
    const pqxx::row& tuple,
    const std::string& shapeName = std::string());

class AttributeDumper {
public:
    AttributeDumper(
        const std::string& ns,
        json::ObjectBuilder& builder);

    void dumpCategory() const;
    void dumpCategory(const std::string& catName) const;

    template <typename T>
    bool dump(const std::string& name, const pqxx::row& tuple) const
    {
        const auto value = tuple.at(name);
        return value.is_null() ? false : dump(name, value.as<T>());
    }

    template <typename T>
    bool dump(const std::string& name, const T& value) const
    {
        return dump(ns_, name, value);
    }

    template <typename T>
    bool dump(const std::string& catName, const std::string& attrName, const T& value) const
    {
        return dump(catName, attrName, std::to_string(value));
    }

private:
    const std::string ns_;
    json::ObjectBuilder& builder_;
};

template <>
bool AttributeDumper::dump<std::string>(
    const std::string& catName,
    const std::string& attrName,
    const std::string& value) const;

template <>
bool AttributeDumper::dump<bool>(
    const std::string& catName,
    const std::string& attrName,
    const bool& value) const;

} //maps
