#include "tls.h"

#include <library/cpp/string_utils/base64/base64.h>

template <typename F>
static void ReadPEM(IInputStream& in, F&& f) {
    bool firstLine = true;
    TString lastKind;
    TString buffer;
    for (TString line; in.ReadLine(line); firstLine = false) {
        if (lastKind) {
            if (line == "----- END " + lastKind + " -----") {
                f(lastKind, Base64Decode(buffer));
                lastKind.clear();
            } else {
                buffer += line;
            }
        } else if (line) {
            Y_ENSURE((firstLine || TStringBuf(line).StartsWith("----- BEGIN ")) &&
                     TStringBuf(line).EndsWith(" -----"), "not a valid PEM file");
            lastKind = line.substr(firstLine ? 0 : 12, line.size() - (firstLine ? 6 : 18));
        }
    }
    Y_ENSURE(!lastKind, "truncated PEM file");
}

TVector<std::array<ui8, 48>> NSv::ReadTicketKeys(IInputStream& in) {
    std::array<ui8, 48> buf;
    Y_ENSURE(in.Load(buf.data(), 12) == 12, "file too short");
    if (TStringBuf((const char*)buf.data(), 12) != "----- BEGIN ") {
        char c;
        Y_ENSURE(in.Load(buf.data() + 12, 36) == 36, "file too short");
        Y_ENSURE(in.Load(&c, 1) == 0, "file too long");
        return {buf};
    }
    TVector<std::array<ui8, 48>> ret;
    ReadPEM(in, [&](const TString& kind, const TString& str) {
        if (kind != "SESSION TICKET KEY") {
            return;
        }
        Y_ENSURE(str.size() == 48, "ticket key of length " << str.size() << ", expected 48");
        ret.emplace_back();
        memcpy(ret.back().data(), str.data(), 48);
    });
    return ret;
}
