#include "reqid.h"

#include <util/stream/str.h>

namespace NSrvKernel {

    namespace {
        void AppendHexEncoded(IOutputStream& reqidStream, ui64 rndBuf) noexcept {
            const char hexDigits[17] = "0123456789abcdef";

            for (int i = 0; i < 8; ++i) {
                reqidStream << hexDigits[(rndBuf & 0xFF) >> 4] << hexDigits[rndBuf & 0xF];
                rndBuf >>= 8;
            }
        }
    }

    void GenReqId(IOutputStream& out, const TInstant start, const ui64 random) noexcept {
        out << start.MicroSeconds() << '-' << random;
    }

    void GenSearchReqId(IOutputStream& out, const TInstant start, const ui64 random, TStringBuf hostname) noexcept {
        GenReqId(out, start, random);
        TStringBuf domain;
        TStringBuf junk;
        if (hostname.TrySplit('.', domain, junk)) {
            out << '-' << domain;
        }
        out << "-BAL";
    }

    void GenMarketReqId(IOutputStream& out, const TInstant start, const ui64 random) noexcept {
        // BALANCER-2554
        out << start.MilliSeconds() << "/";
        // Add the first 16 bytes from Random
        AppendHexEncoded(out, random);
        // Add the second 16 bytes from start microseconds
        AppendHexEncoded(out, start.MicroSeconds());
    }

    void GenAdfoxReqId(IOutputStream& out, const ui64 random) noexcept {
        out << random;
    }

    TString GenReqId(const TInstant start, const ui64 random) noexcept {
        TStringStream str;
        str.Str().reserve(20 + 1 + 20 + 1);
        GenReqId(str, start, random);
        return str.Str();
    }

    TString GenMarketReqId(const TInstant start, const ui64 random) noexcept {
        TStringStream str;
        str.Str().reserve(20 + 1 + 32 + 1);
        GenMarketReqId(str, start, random);
        return str.Str();
    }

    TString GenAdfoxReqId(const ui64 random) noexcept {
        TStringStream str;
        str.Str().reserve(20 + 1 + 20 + 1);
        GenAdfoxReqId(str, random);
        return str.Str();
    }

    TString GenSearchReqId(const TInstant start, const ui64 random, TStringBuf hostname) noexcept {
        TStringStream str;
        str.Str().reserve(20 + 1 + 20 + 1 + 20);
        GenSearchReqId(str, start, random, hostname);
        return str.Str();
    }
}
