#pragma once

#include <maps/wikimap/mapspro/libs/stat_client/include/common.h>
#include <maps/wikimap/mapspro/libs/stat_client/include/report.h>

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

#include <chrono>
#include <sstream>
#include <string>

namespace maps::wiki::stat_client {

/// Uploads a report to Yandex Stat.
class Uploader {
public:
    Uploader(std::string statUploadApiUrl);

    /// Sets whether append/rewrite existing data in a scale or totally remove
    ///   them from this scale during upload.
    Uploader& mode(Mode mode);

    /// Sets uploading timeout.
    ///
    /// Information from the [report history](https://stat.yandex-team.ru/<report name>/.history)
    /// could be used as a guideline to set this parameter. (see `info.timing` field)
    Uploader& timeout(std::chrono::seconds timeout);

    /// Uploads a report in form of plain text (in a supported format).
    ///
    /// @param reportName Report name, it is equal to the *path* part of the report
    ///   URL. For example, the name of a report `ShinyReport` located under the
    ///   directory `Maps.Wiki/ShinyReports` is `Maps.Wiki/ShinyReports/ShinyReport`,
    ///   this report can be found at https://stat.yandex-team.ru/Maps.Wiki/ShinyReports/ShinyReport.
    /// @param reportBody Data in any supported by Yandex Stat format: JSON,
    ///   CSV, TSKV or TSV.
    /// @param scale Scale the data belongs to.
    void upload(const std::string& reportName, const std::string& reportBody, Scale scale);

    /// Uploads a stat_client::Report.
    template <typename Dimensions, typename Measures, Scale scale>
    void upload(const Report<Dimensions, Measures, scale>& report) {
        std::ostringstream oss;
        csv::OutputStream outCsv(oss);
        report.print(outCsv);
        upload(report.name, oss.str(), report.scale);
    }

private:
    const std::string statUploadApiUrl_;
    Mode mode_ = Mode::Truncate;
    std::chrono::seconds timeout_ = std::chrono::seconds(60);
};

} // namespace maps::wiki::stat_client
