#pragma once

#include "formatter.h"

namespace maps {
namespace wiki {
class FormatterContext;

class JSONFormatter: public Formatter
{
public:
    JSONFormatter(std::unique_ptr<FormatterContext>&& context)
        : Formatter(std::move(context)) {}

    virtual std::string formatException(const maps::Exception& ex, bool withBacktrace);

    virtual std::string operator ()(const ResultType<SaveObject>& result);
    virtual std::string operator ()(const ResultType<CreateIntersections>& result);
    virtual std::string operator ()(const ResultType<CloneObject>& result);
    virtual std::string operator ()(const ResultType<ObjectsUpdateAttributes>& result);
    virtual std::string operator ()(const ResultType<ObjectsUpdateAttributesMeta>& result);
    virtual std::string operator ()(const ResultType<ObjectsUpdateState>& result);
    virtual std::string operator ()(const ResultType<ObjectsUpdateStateMeta>& result);
    virtual std::string operator ()(const ResultType<ObjectsUpdateMove>& result);
    virtual std::string operator ()(const ResultType<ObjectsUpdateMoveMeta>& result);
    virtual std::string operator ()(const ResultType<ObjectsUpdateSyncGeometry>& result);
    virtual std::string operator ()(const ResultType<ObjectsUpdateSyncGeometryMeta>& result);
    virtual std::string operator ()(const ResultType<ObjectsUpdateRelation>&result);
    virtual std::string operator ()(const ResultType<ObjectsUpdateUnion>& result);
    virtual std::string operator ()(const ResultType<ObjectsUpdateUnionMeta>& result);
    virtual std::string operator ()(const ResultType<ObjectsUpdateMerge>& result);
    virtual std::string operator ()(const ResultType<ObjectsUpdateSnap>& result);
    virtual std::string operator ()(const ResultType<ObjectsUpdateSnapMeta>& result);

    virtual std::string operator ()(const ResultType<ObjectsCleanupRelations>& result);
    virtual std::string operator ()(const ResultType<ObjectsUpdateRelations>& result);
    virtual std::string operator ()(const ResultType<ObjectsUpdateRelationsMeta>& result);

    virtual std::string operator ()(const ResultType<GetObject>& result);

    virtual std::string operator ()(const ResultType<GetHistory>& result);

    virtual std::string operator ()(const ResultType<GetTopology>& result);

    virtual std::string operator ()(const ResultType<ToolsPedestrianPoints>& )
    { UNSUPPORTED_FORMAT(common::FormatType::JSON, "ToolsPedestrianPoints"); }
    virtual std::string operator ()(const ResultType<ToolsSavePedestrianPoints>& )
    { UNSUPPORTED_FORMAT(common::FormatType::JSON, "ToolsSavePedestrianPoints"); }
    virtual std::string operator ()(const ResultType<ToolsLoadPedestrianPoints>& )
    { UNSUPPORTED_FORMAT(common::FormatType::JSON, "ToolsLoadPedestrianPoints"); }

    virtual std::string operator ()(const ResultType<GetObjectsByTile>& result);
    virtual std::string operator ()(const ResultType<ObjectsQueryLasso>&);
    virtual std::string operator ()(const ResultType<ObjectsQueryLassoMeta>&);
    virtual std::string operator ()(const ResultType<ObjectsQueryTitle>&);
    virtual std::string operator ()(const ResultType<ObjectsQueryPoiBusinessId>&);
    virtual std::string operator ()(const ResultType<ObjectsQueryIds>&);

    virtual std::string operator ()(const ResultType<ObjectsQueryCategory>&);

    virtual std::string operator ()(const ResultType<ObjectsQueryFilter>&);
    virtual std::string operator ()(const ResultType<ObjectsQueryRouteDiff>& result);
    virtual std::string operator ()(const ResultType<GetRouteTime>& result);
    virtual std::string operator ()(const ResultType<ObjectsQueryPath>& result);
    virtual std::string operator ()(const ResultType<ObjectsQueryPoiConflicts>&);
    virtual std::string operator ()(const ResultType<ObjectsQueryPoisConflicts>& result);
    virtual std::string operator ()(const ResultType<ObjectsQueryPoisConflictsMeta>& result);

    virtual std::string operator ()(const ResultType<ToolsResolvePoisConflicts>& result);
    virtual std::string operator ()(const ResultType<ToolsResolvePoisConflictsMeta>& result);

    virtual std::string operator ()(const ResultType<GetAsyncResult>& result);
    virtual std::string operator ()(const ResultType<GetSlaveInfos>& result);

    virtual std::string operator ()(const ResultType<GetLayers>& result);
    virtual std::string operator ()(const ResultType<GetLayers2>& result);

    virtual std::string operator ()(const ResultType<GetFilters>& result);
    virtual std::string operator ()(const ResultType<SaveFilter>& result);
    virtual std::string operator ()(const ResultType<DeleteFilter>& result);
    virtual std::string operator ()(const ResultType<SaveExpression>& result);
    virtual std::string operator ()(const ResultType<GetFilterExpression>&)
    { UNSUPPORTED_FORMAT(common::FormatType::JSON, "GetFilterExpression"); }

    virtual std::string operator ()(const ResultType<GetSuggest>& result);
    virtual std::string operator ()(const ResultType<GetBranches>& result);

    virtual std::string operator ()(const ResultType<SaveBranchType>&/*result*/)
    { UNSUPPORTED_FORMAT(common::FormatType::JSON, "SaveBranchType"); }

    virtual std::string operator ()(const ResultType<SaveBranchState>&/*result*/)
    { UNSUPPORTED_FORMAT(common::FormatType::JSON, "SaveBranchState"); }

    virtual std::string operator ()(const ResultType<GetValidationExclusions>& result);

    virtual std::string operator ()(const ResultType<AsyncBaseController>& result);
    virtual std::string operator ()(const ResultType<SaveValidationExclusion>& result);
    virtual std::string operator ()(const ResultType<ViewValidationExclusion>& result);

    virtual std::string operator ()(const ResultType<GetGeoLocks>& result);
    virtual std::string operator ()(const ResultType<GetCommitDiff>& result);
    virtual std::string operator ()(const ResultType<GetCommitGeomDiff>& result);
    virtual std::string operator ()(const ResultType<GetBranchDiff>&/*result*/)
    { UNSUPPORTED_FORMAT(common::FormatType::JSON, "GetBranchDiff"); }
    virtual std::string operator ()(const ResultType<CreateToken>& result);

    virtual std::string operator ()(const ResultType<GetSocialFeed>& result);
    virtual std::string operator ()(const ResultType<GetRegularSocialFeedMeta>& result);
    virtual std::string operator ()(const ResultType<GetSocialSubscriptions>& result);
    virtual std::string operator ()(const ResultType<SocialModerationRegions>& result);
    virtual std::string operator ()(const ResultType<SocialModerationTasksAcquire>& result);
    virtual std::string operator ()(const ResultType<SocialModerationTasksAcquireBlocking>& result);
    virtual std::string operator ()(const ResultType<SocialModerationTasksRelease>& result);
    virtual std::string operator ()(const ResultType<SocialModerationTasksResolve>& result);
    virtual std::string operator ()(const ResultType<SocialModerationTasksClose>& result);
    virtual std::string operator ()(const ResultType<SocialModerationTasksDefer>& result);
    virtual std::string operator ()(const ResultType<SocialModerationTasksStat>& result);
    virtual std::string operator ()(const ResultType<GetSocialModerationTask>& result);
    virtual std::string operator ()(const ResultType<GetSocialModerationTaskByCommit>& result);
    virtual std::string operator ()(const ResultType<GetSocialModerationStat>& result);
    virtual std::string operator ()(const ResultType<GetSocialModerationTasks>& result);
    virtual std::string operator ()(const ResultType<GetSocialEvent>& result);
    virtual std::string operator ()(const ResultType<SocialModerationDashboard>& result);
    virtual std::string operator ()(const ResultType<SocialModerationDashboardMeta>& result);
    virtual std::string operator ()(const ResultType<GetSocialFeedbackTaskHistory>& result);
    virtual std::string operator ()(const ResultType<GetSocialFeedbackTaskStat>& result);

    virtual std::string operator ()(const ResultType<CreateSpravTask>&);
    virtual std::string operator ()(const ResultType<GetSpravTasks>&);

    virtual std::string operator ()(const ResultType<GetCommentsFeed>& result);
    virtual std::string operator ()(const ResultType<GetCommentsStat>& result);
    virtual std::string operator ()(const ResultType<ClearUserComments>& result);
    virtual std::string operator ()(const ResultType<CommentsCreate>& result);
    virtual std::string operator ()(const ResultType<CommentsDelete>& result);

    virtual std::string operator ()(const ResultType<GetCommit>& result);
    virtual std::string operator ()(const ResultType<CommitsApprove>& result);
    virtual std::string operator ()(const ResultType<CommitsRevert>& result);
    virtual std::string operator ()(const ResultType<GetDependentCommits>& result);
    virtual std::string operator ()(const ResultType<ObjectsQueryJunction>& result);

    virtual std::string operator ()(const ResultType<BusinessPhotos>& result);
    virtual std::string operator ()(const ResultType<DistributeFlats>& result);
    virtual std::string operator ()(const ResultType<PointToBld>& result);

    virtual std::string operator ()(const AsyncTaskResult&);
};

std::string
tokenTaskResponseJson(const std::string& taskName, const Token& token);

} // namespace wiki
} // namespace maps
