#include <maps/wikimap/mapspro/services/tasks-ng/modules/common.h>
#include <maps/wikimap/mapspro/services/tasks-ng/modules/revision_helpers.h>

namespace maps {
namespace wiki {
namespace tasks_ng {
namespace modules {
namespace apply_shadow_attributes {

const std::string TASK_TYPE = "apply_shadow_attributes";
const std::string TABLE_TASK = "service." + TASK_TYPE + "_task";
const std::string FIELDS_TASK = "branch_id";

class Context : public TaskContext
{
public:
    explicit Context(const pqxx::row& row)
        : branchId(row[0].as<Id>())
    {}

    void write(XmlWriter& writer, TaskWriteMode) const override
    {
        writer.addTag("apply-shadow-attributes-context", [&] {
            writer.addTagData("branch", branchId);
        });
    }

    const Id branchId;
};


class Module : public TaskModule
{
public:
    std::string name() const override { return TASK_TYPE; }

    void loadContext(DbContext& ctx, Task& task) const override
    {
        task.loadContext<Context>(ctx, TABLE_TASK, FIELDS_TASK);
    }

    void onCreate(
        DbContext& ctx,
        Task& task,
        const RequestParameters& parameters) const override
    {
        auto& txnCore = ctx.txnCore();

        auto branch = getBranch(ctx, parameters);

        auto query = Query()
            .insertInto(TABLE_TASK)
            .columns("id, " + FIELDS_TASK)
            .values(Query() << task.id() << ',' << branch.id())
            .returning(FIELDS_TASK);

        auto rows = txnCore.exec(query.str());
        ASSERT(rows.size() == 1);

        task.setContext(std::make_unique<Context>(rows[0]));
    }

    json::Value launchParameters(const Task& task) const override
    {
        const auto& ctx = task.context<Context>();

        return json::Value{
            { TYPE, json::Value{TASK_TYPE} },
            { TASK_ID, json::Value{task.id()} },
            { UID, json::Value{task.createdBy()} },
            { BRANCH_ID, json::Value{ctx.branchId} }
        };
    }
};

const auto module = TaskModuleRegistry::get().registerModule<Module>();

} // namespace apply_shadow_attributes
} // namespace modules
} // namespace tasks_ng
} // namespace wiki
} // namespace maps
