#include "header_validation.h"

#include <balancer/kernel/regexp/regexp_pire.h>

#include <util/generic/strbuf.h>

// TODO: replace this with constexpr THashSet
const THashSet<TString, TCIOps, TCIOps> RestrictedHeaders = {"content-length", "transfer-encoding"};
const TStringBuf RestrictedHeadersString = "\"Content-Length, Transfer-Encoding\"";

namespace NSrvKernel {
    bool CheckHeaderName(TStringBuf name) noexcept {
        if (name.empty()) {
            return false;
        }
        for (ui8 ch: name) {
            switch (ch) {
                case 0 ... 0x20:
                case 0x7f ... 0xff:
                case '(':
                case ')':
                case '<':
                case '>':
                case '@':
                case ',':
                case ';':
                case ':':
                case '\\':
                case '"':
                case '/':
                case '[':
                case ']':
                case '?':
                case '=':
                case '{':
                case '}':
                    return false;
            }
        }
        return true;
    }

    bool CheckHeaderValue(TStringBuf val) noexcept {
        for (auto ch: val) {
            switch (ch) {
                case '\r':
                case '\n':
                case '\0':
                    return false;
            }
        }
        return true;
    }

    bool CheckRestrictedHeaderName(TStringBuf val) noexcept {
        return RestrictedHeaders.find(val) == RestrictedHeaders.end();
    }

    bool CheckRestrictedHeaderRegexp(const NRegExp::TFsm& fsm) noexcept {
        for (auto& it: RestrictedHeaders) {
            NRegExp::TMatcher matcher(fsm);
            if (Match(matcher, it).Final()) {
                return false;
            }
        }

        return true;
    }

    const TStringBuf RestrictedHeadersListString() noexcept {
        return RestrictedHeadersString;
    }
}
