#pragma once

#include <yweb/fleur/util/metrics/metrics.h>

#include <library/cpp/regex/pcre/regexp.h>

#include <util/generic/ptr.h>

#include <atomic>

class IThreadPool;
class TBlob;
class TNetworkAddress;
class TBaseServerRequestData;

class TFlowMirror {
public:
    struct TConfig {
    public:
        struct TSlice {
            TRegExMatch CompiledRegexp;
            TString Regexp;
            float Fraction = 0.1f;
        };

    public:
        TString Host = "localhost";
        TVector<TSlice> Slices;
        ui16 Port = 10000;
        ui16 Threads = 1;
        TDuration Timeout = TDuration::MilliSeconds(50);
        float Fraction = 0.1f;
        bool Enabled = false;
        bool CopyHeaders = false;
    };

protected:
    class TReq;

public:
    TFlowMirror(const TConfig& config);
    ~TFlowMirror();
    const TConfig& GetConfig() const;
    void RegisterMetrics(TMetrics& controller);
    void UnregisterMetrics(TMetrics& controller);
    bool ProcessRequest(const TString& request,
                        const TBaseServerRequestData& rd,
                        const TBlob& data);

protected:
    void DoProcessRequest(const TReq* req);
    bool SelectRequest(const TString& request);

protected:
    const TConfig Config;
    THolder<TNetworkAddress> Address;
    THolder<IThreadPool> Queue;

    TQueriesMetrics Redirected;
    TOrangeMetric Failed;

    std::atomic<bool> StopFlag;
};
