#pragma once

#include <yandex/maps/wiki/mds_dataset/types.h>

#include <pqxx/pqxx>

#include <memory>
#include <string>

namespace maps {
namespace wiki {
namespace mds_dataset {

/**
 * @brief Describes common sql filters to manage datasets loading rules
 * Filters can be chained in which case they are be combined with logical 'AND'
 */
template <typename Self>
class Filter
{
public:
    explicit Filter(pqxx::transaction_base& txn);
    virtual ~Filter();

    Filter(Filter&& filter) = default;
    Filter& operator=(Filter&& filter) = default;

    Self& byId(const DatasetID& id);

    Self& byStatus(DatasetStatus status);

    Self& byRegion(const Region& region);

    /// @brief Filter datasets created after given time point
    ///        with seconds precision
    Self& createdAfter(Timestamp created);

    /// @brief Filter datasets created before given time point
    ///        with seconds precision
    Self& createdBefore(Timestamp created);

    /// @return the complete "WHERE ..." clause built according to the filters
    std::string toSql() const;

protected:
    void addClause(std::string clause);

private:
    class Impl;
    std::unique_ptr<Impl> pimpl_;
};

class ExportMetadata;

/**
 * @brief Specific sql filters for Export datasets
 */
class ExportFilter : public Filter<ExportFilter>
{
public:
    typedef ExportMetadata MetadataType;

    explicit ExportFilter(pqxx::transaction_base& txn);
    virtual ~ExportFilter();

    ExportFilter(ExportFilter&& filter) = default;
    ExportFilter& operator=(ExportFilter&& filter) = default;

    ExportFilter& bySubset(Subset subset);
    ExportFilter& tested(bool isTested);
};


} // mds_dataset
} // wiki
} // maps
