#include "common.h"

#include <util/folder/dirut.h>
#include <util/folder/path.h>
#include <util/generic/yexception.h>
#include <util/stream/file.h>
#include <util/string/strip.h>
#include <util/string/vector.h>
#include <util/system/env.h>

namespace {
    TString GetToken(const TString& tokenPath, const TString& tokenEnv) {
        {
            TFsPath lbTokenPath = TFsPath(GetHomeDir()) / tokenPath;
            if (lbTokenPath.Exists()) {
                TUnbufferedFileInput file(lbTokenPath);
                return Strip(file.ReadAll());
            }
        }
        {
            TString lbToken = Strip(GetEnv(tokenEnv));
            if (lbToken) {
                return lbToken;
            }
        }
        ythrow yexception() << "cannot get token " << tokenEnv;
    }
}

namespace NSaasLB {
    TString GetLogbrokerToken() {
        return GetToken(".logbroker/token", "LOGBROKER_TOKEN");
    }

    std::optional<TString> GetLogbrokerRemoteMirrorRulesToken() {
        try {
            return GetToken(".logbroker/mirror-token", "LOGBROKER_MIRROR_TOKEN");
        } catch(...) {
            return {};
        }
    }

    std::optional<TTopicInfo> GetTopicInfo(const TString& topic) {
        // rt3.<cluster>--<directory>--<name>:partition
        // example: rt3.vla--saas@services@service_name@service_ctype@topics--shard-8736-13103:0
        if (topic.StartsWith("rt3.")) {
            auto parts = SplitString(topic, "--");
            if (parts.size() == 3) {
                auto prefixParts = SplitString(parts[0], ".");
                if (prefixParts.size() == 2) {
                    auto suffixParts = SplitString(parts.back(), ":");
                    if (suffixParts.size() == 2) {
                        TTopicInfo info;
                        info.Cluster = prefixParts[1];
                        info.Directory = parts[1];
                        info.Name = suffixParts[0];
                        if (!TryFromString<ui32>(suffixParts[1], info.Partition)) {
                            return {};
                        }
                        return info;
                    }
                }
            }
        }
        return {};
    }

    TString MaskToken(const TString& token) {
        size_t publicSize = token.size() / 4;
        size_t privateSize = token.size() - publicSize;
        size_t start = publicSize / 2;

        TString maskedToken = token;
        std::fill(maskedToken.begin() + start, maskedToken.begin() + start + privateSize, '*');

        return maskedToken;
    }
}
