#include "../common.h"
#include "../categories.h"
#include "../magic_strings.h"
#include "../attribute_dumper.h"

#include <yandex/maps/wiki/common/pg_utils.h>

#include <maps/libs/log8/include/log8.h>

namespace maps {

namespace {
const std::string BLD_ID = "bld_id";
const std::string COND = "cond";
const std::string PATH = "path";
const std::string FT_TYPE_ID = "ft_type_id";
const std::string HEIGHT = "height";
} //namespace

struct BldCategory: public Category {
    const Table& table() const override
    {
        return table::BLD;
    }

    std::string loadRowsSqlTemplate() const override
    {
        return "WITH tmp as "
            "(WITH paged_bld AS (SELECT bld_id, ft_type_id, cond, height FROM bld WHERE bld_id IN %1%) "
            "SELECT"
            " paged_bld.bld_id as bld_id,"
            " paged_bld.ft_type_id as ft_type_id,"
            " paged_bld.cond as cond,"
            " paged_bld.height as height,"
            " ST_Dump(ST_BuildArea(ST_Collect(edge.shape))) as shape "
            "FROM paged_bld "
            "JOIN bld_face ON (bld_face.bld_id = paged_bld.bld_id) "
            "JOIN face_edge ON (face_edge.face_id = bld_face.face_id) "
            "JOIN edge ON (edge.edge_id = face_edge.edge_id) "
            "GROUP BY"
            " paged_bld.bld_id,"
            " paged_bld.ft_type_id,"
            " paged_bld.cond,"
            " paged_bld.height)"
            "  SELECT bld_id id, ft_type_id, cond, (shape).path, ST_AsGeoJson((shape).geom) as shape, height FROM tmp";
    }

    void tupleToJson(
        json::ObjectBuilder& builder,
        const pqxx::row& tuple) const override
    {
        if (!wiki::common::parseSqlArray(tuple.at(PATH).as<std::string>()).empty()) {
            ERROR() << "oid=" << tuple.at(ID).as<DBID>() << ", building has more then one polygon";
            return;
        }

        builder[jkey::ATTRIBUTES] = [&](json::ObjectBuilder builder) {
            AttributeDumper ad(name(), builder);
            ad.dumpCategory();
            ad.dump<std::string>(FT_TYPE_ID, tuple);
            ad.dump<std::string>(COND, tuple);
            ad.dump<std::string>(HEIGHT, tuple);
        };
        dumpGeometry(builder, tuple);
    }
};

DEFINE_CATEGORY_OBJECT(Bld, BLD);

} // namespace maps
