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

namespace maps {

namespace {
const std::string RD_EL_IDS = "rd_el_ids";
const std::string RD_ID = "rd_id";
const std::string AD_ID = "ad_id";
const std::string RD_TYPE = "rd_type";
const std::string SEARCH_CLASS = "search_class";
} // namespace

struct RdCategory: public Category {
    const Table& table() const override
    {
        return table::RD;
    }

    std::string loadRowsSqlTemplate() const override
    {
        return "WITH paged_rd AS (SELECT * FROM rd WHERE rd_id IN %1%) "
            "SELECT"
            " paged_rd." + RD_ID + " " + ID + "," +
            " paged_rd." + RD_TYPE + "," +
            " paged_rd." + SEARCH_CLASS + "," +
            " (SELECT rd_ad.ad_id FROM rd_ad" +
                " WHERE rd_ad.rd_id = paged_rd.rd_id) " + AD_ID + "," +
            " (SELECT array_agg(rd_rd_el.rd_el_id) FROM rd_rd_el" +
                " WHERE rd_rd_el.rd_id = paged_rd.rd_id) " + RD_EL_IDS + " " +
            "FROM paged_rd";
    }

    void tupleToJson(
        json::ObjectBuilder& builder,
        const pqxx::row& tuple) const override
    {
        builder[jkey::ATTRIBUTES] = [&](json::ObjectBuilder builder) {
            AttributeDumper ad(name(), builder);
            ad.dumpCategory();
            ad.dump<int>(RD_TYPE, tuple);
            ad.dump<int>(SEARCH_CLASS, tuple);
        };

        builder[jkey::RELATIONS] = [&](json::ArrayBuilder builder) {
            RelationDumper rd(builder, tuple);
            rd.dump(relation::RD_PART, RD_EL_IDS);
            rd.dump(relation::AD_ASSOCIATED_WITH, AD_ID);
        };
    }
};

DEFINE_CATEGORY_OBJECT(Rd, RD);

} // namespace maps
