/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "paimon/rest/dlf_auth.h"

#include <atomic>
#include <chrono>
#include <fstream>
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <thread>
#include <utility>
#include <vector>

#include "gtest/gtest.h"
#include "paimon/catalog_options.h"
#include "paimon/testing/utils/testharness.h"

namespace paimon::test {

namespace {

using StringMap = std::map<std::string, std::string>;

std::chrono::system_clock::time_point FixedTime() {
    return std::chrono::system_clock::from_time_t(1744775086);
}

class SequenceTokenLoader : public DlfTokenLoader {
 public:
    explicit SequenceTokenLoader(
        std::vector<DlfToken> tokens,
        std::chrono::milliseconds load_delay = std::chrono::milliseconds(0))
        : tokens_(std::move(tokens)), load_delay_(load_delay) {}

    Result<DlfToken> LoadToken() override {
        std::this_thread::sleep_for(load_delay_);
        int32_t index = load_count_.fetch_add(1);
        if (index >= static_cast<int32_t>(tokens_.size())) {
            return Status::Invalid("test token loader exhausted");
        }
        return tokens_[index];
    }

    std::string Description() const override {
        return "test sequence";
    }

    int32_t GetLoadCount() const {
        return load_count_.load();
    }

 private:
    std::vector<DlfToken> tokens_;
    std::chrono::milliseconds load_delay_;
    std::atomic<int32_t> load_count_{0};
};

class MockEcsHttpClient : public HttpClient {
 public:
    explicit MockEcsHttpClient(const std::string& metadata_url, bool direct_token = false)
        : metadata_url_(metadata_url), direct_token_(direct_token) {}

    Result<HttpResponse> Execute(const HttpRequest& request,
                                 const HttpBodyConsumer& consumer) const override {
        last_request_timeout_ms_.store(request.request_timeout_ms);
        HttpResponse response;
        response.status_code = 200;
        std::string body;
        if (request.url == metadata_url_) {
            if (direct_token_) {
                token_requests_.fetch_add(1);
                body = R"({"AccessKeyId":"ecs-ak","AccessKeySecret":"ecs-sk",)"
                       R"("SecurityToken":"ecs-sts","Expiration":"2027-04-16T05:44:46Z"})";
            } else {
                role_requests_.fetch_add(1);
                body = " test-role\n";
            }
        } else if (request.url == metadata_url_ + "test-role") {
            token_requests_.fetch_add(1);
            body = R"({"AccessKeyId":"ecs-ak","AccessKeySecret":"ecs-sk",)"
                   R"("SecurityToken":"ecs-sts","Expiration":"2027-04-16T05:44:46Z"})";
        } else {
            response.status_code = 404;
        }
        if (!body.empty()) {
            PAIMON_RETURN_NOT_OK(consumer(body.data(), static_cast<int64_t>(body.size())));
            response.body_size = static_cast<int64_t>(body.size());
        }
        return response;
    }

    int32_t GetRoleRequestCount() const {
        return role_requests_.load();
    }

    int32_t GetTokenRequestCount() const {
        return token_requests_.load();
    }

    int64_t GetLastRequestTimeoutMillis() const {
        return last_request_timeout_ms_.load();
    }

 private:
    std::string metadata_url_;
    bool direct_token_;
    mutable std::atomic<int32_t> role_requests_{0};
    mutable std::atomic<int32_t> token_requests_{0};
    mutable std::atomic<int64_t> last_request_timeout_ms_{-1};
};

class FailingEcsHttpClient : public HttpClient {
 public:
    Result<HttpResponse> Execute(const HttpRequest&, const HttpBodyConsumer&) const override {
        return Status::IOError("connection refused");
    }
};

}  // namespace

TEST(DlfDefaultSignerTest, SignsJavaCompatibleRequest) {
    DlfDefaultSigner signer("cn-beijing");
    const std::string body = R"({"name":"t1"})";
    DlfToken token("YourAccessKeyId", "YourAccessKeySecret", "securityToken", std::nullopt);
    RestAuthParameter parameter =
        RestAuthParameter::Create("POST", "/v1/wh/databases/db/tables",
                                  {{"warehouse", "my instance"}, {"branch", "main"}}, body);

    ASSERT_OK_AND_ASSIGN(DlfRequestSigner::Headers headers,
                         signer.SignHeaders(body, FixedTime(), token.GetSecurityToken(), "unused"));
    ASSERT_EQ("20250416T034446Z", headers.at("x-dlf-date"));
    ASSERT_EQ("Od9T1x3c2+JusJPFMpXe9Q==", headers.at("Content-MD5"));
    ASSERT_EQ("application/json", headers.at("Content-Type"));
    ASSERT_EQ("UNSIGNED-PAYLOAD", headers.at("x-dlf-content-sha256"));
    ASSERT_EQ("v1", headers.at("x-dlf-version"));
    ASSERT_EQ("securityToken", headers.at("x-dlf-security-token"));

    ASSERT_OK_AND_ASSIGN(std::string authorization,
                         signer.Authorization(parameter, token, "unused", headers));
    ASSERT_EQ(
        "DLF4-HMAC-SHA256 Credential=YourAccessKeyId/20250416/cn-beijing/"
        "DlfNext/aliyun_v4_request,Signature="
        "22594f8bbb8bb0ec296ced6003b7ffdf7022a8ca3815da5b53090daa11a06558",
        authorization);
}

TEST(DlfDefaultSignerTest, MatchesJavaGoldenAuthorization) {
    // Mirrors Java DLFAuthSignatureTest#testGetAuthorization.
    DlfDefaultSigner signer("cn-hangzhou");
    const std::string body = R"({"name":"database","options":{"a":"b"}})";
    DlfToken token("access-key-id", "access-key-secret", "securityToken", std::nullopt);
    RestAuthParameter parameter = RestAuthParameter::Create("POST", "/v1/paimon/databases",
                                                            {{"k1", "v1"}, {"k2", "v2"}}, body);
    const std::chrono::system_clock::time_point signing_time =
        std::chrono::system_clock::from_time_t(1701605532);

    ASSERT_OK_AND_ASSIGN(DlfRequestSigner::Headers headers,
                         signer.SignHeaders(body, signing_time, token.GetSecurityToken(), "host"));
    ASSERT_OK_AND_ASSIGN(std::string authorization,
                         signer.Authorization(parameter, token, "host", headers));
    ASSERT_EQ(
        "DLF4-HMAC-SHA256 Credential=access-key-id/20231203/cn-hangzhou/"
        "DlfNext/aliyun_v4_request,Signature="
        "c72caf1d40b55b1905d891ee3e3de48a2f8bebefa7e39e4f277acc93c269c5e3",
        authorization);
}

TEST(DlfDefaultSignerTest, OmitsBodyAndSecurityTokenHeadersWhenAbsent) {
    DlfDefaultSigner signer("cn-hangzhou");
    ASSERT_OK_AND_ASSIGN(DlfRequestSigner::Headers headers,
                         signer.SignHeaders("", FixedTime(), std::nullopt, "unused"));
    ASSERT_EQ(3, headers.size());
    ASSERT_EQ(0, headers.count("Content-MD5"));
    ASSERT_EQ(0, headers.count("Content-Type"));
    ASSERT_EQ(0, headers.count("x-dlf-security-token"));
}

TEST(DlfOpenApiSignerTest, SignsJavaCompatibleRequest) {
    DlfOpenApiSigner signer;
    const std::string body = R"({"CategoryName":"test","CategoryType":"UNSTRUCTURED"})";
    const std::string host = "dlfnext.cn-beijing.aliyuncs.com";
    DlfToken token("YourAccessKeyId", "YourAccessKeySecret", "securityToken", std::nullopt);
    RestAuthParameter parameter =
        RestAuthParameter::Create("POST", "/llm-p2e4XXXXXXXXsvtn/datacenter/category", {}, body);

    ASSERT_OK_AND_ASSIGN(DlfRequestSigner::Headers headers,
                         signer.SignHeaders(body, FixedTime(), token.GetSecurityToken(), host));
    headers["x-acs-signature-nonce"] = "ef34aae7-7bd2-413d-a541-680cd2c48538";
    ASSERT_EQ("Wed, 16 Apr 2025 03:44:46 GMT", headers.at("Date"));
    ASSERT_EQ("q2qaEcR4P47+Z7CUzHRTBw==", headers.at("Content-MD5"));
    ASSERT_EQ("application/json", headers.at("Accept"));
    ASSERT_EQ("application/json", headers.at("Content-Type"));
    ASSERT_EQ(host, headers.at("Host"));
    ASSERT_EQ("HMAC-SHA1", headers.at("x-acs-signature-method"));
    ASSERT_EQ("1.0", headers.at("x-acs-signature-version"));
    ASSERT_EQ("2026-01-18", headers.at("x-acs-version"));
    ASSERT_EQ("securityToken", headers.at("x-acs-security-token"));

    ASSERT_OK_AND_ASSIGN(std::string authorization,
                         signer.Authorization(parameter, token, host, headers));
    ASSERT_EQ("acs YourAccessKeyId:wX4CDPSCtfgYkxdK9tJIO3ez5VI=", authorization);
}

TEST(DlfOpenApiSignerTest, DecodesPathAndQueryValuesBeforeSigning) {
    DlfOpenApiSigner signer;
    DlfToken token("ak", "sk", std::nullopt, std::nullopt);
    RestAuthParameter parameter = RestAuthParameter::Create(
        "GET", "/v1/%24snapshots", {{"z", ""}, {"name", "hello world"}}, "");
    ASSERT_OK_AND_ASSIGN(DlfRequestSigner::Headers headers,
                         signer.SignHeaders("", FixedTime(), std::nullopt, "host"));
    headers["x-acs-signature-nonce"] = "fixed-nonce";

    ASSERT_OK_AND_ASSIGN(std::string authorization,
                         signer.Authorization(parameter, token, "host", headers));
    ASSERT_EQ("acs ak:vD+M7291KKoOTvt2gQuD6jPDlw8=", authorization);
    ASSERT_EQ(0, headers.count("Content-MD5"));
    ASSERT_EQ(0, headers.count("Content-Type"));
}

TEST(DlfTokenTest, ParsesExpirationAndRefreshBoundary) {
    ASSERT_OK_AND_ASSIGN(
        DlfToken token,
        DlfToken::FromJson(R"({"AccessKeyId":"ak","AccessKeySecret":"sk","SecurityToken":"sts",)"
                           R"("Expiration":"2025-04-16T05:44:46Z","Ignored":"value"})"));
    ASSERT_EQ("ak", token.GetAccessKeyId());
    ASSERT_EQ("sk", token.GetAccessKeySecret());
    ASSERT_EQ(std::optional<std::string>("sts"), token.GetSecurityToken());
    ASSERT_EQ(std::optional<int64_t>(1744782286000), token.GetExpirationAtMillis());
    ASSERT_FALSE(token.ShouldRefresh(FixedTime() + std::chrono::hours(1)));
    ASSERT_TRUE(
        token.ShouldRefresh(FixedTime() + std::chrono::hours(1) + std::chrono::milliseconds(1)));

    DlfToken permanent("ak", "sk", std::nullopt, std::nullopt);
    ASSERT_FALSE(permanent.ShouldRefresh(FixedTime() + std::chrono::hours(100000)));
}

TEST(DlfTokenTest, ParseFailureDoesNotLeakCredentials) {
    const std::string secret = "STSSECRET_AKID_9999";
    Status status =
        DlfToken::FromJson(R"({"AccessKeyId":"ak","AccessKeySecret":")" + secret).status();
    ASSERT_FALSE(status.ok());
    ASSERT_EQ(std::string::npos, status.ToString().find(secret));
}

TEST(DlfLocalFileTokenLoaderTest, LoadsTokenAndRedactsMalformedContent) {
    std::unique_ptr<UniqueTestDirectory> test_dir = UniqueTestDirectory::Create();
    ASSERT_NE(nullptr, test_dir);
    const std::string path = test_dir->Str() + "/dlf-token.json";
    {
        std::ofstream file(path);
        file << R"({"AccessKeyId":"file-ak","AccessKeySecret":"file-sk",)"
                R"("SecurityToken":"file-sts","Expiration":"2027-04-16T05:44:46Z"})";
    }
    DlfLocalFileTokenLoader loader(path, 1, std::chrono::milliseconds(0));
    ASSERT_OK_AND_ASSIGN(DlfToken token, loader.LoadToken());
    ASSERT_EQ("file-ak", token.GetAccessKeyId());
    ASSERT_EQ(std::optional<std::string>("file-sts"), token.GetSecurityToken());

    std::map<std::string, std::string> options = {
        {CatalogOptions::URI, "https://cn-hangzhou-vpc.dlf.aliyuncs.com"},
        {CatalogOptions::TOKEN_PROVIDER, "dlf"},
        {CatalogOptions::DLF_TOKEN_PATH, path},
        {CatalogOptions::DLF_ACCESS_KEY_ID, "ignored-ak"},
        {CatalogOptions::DLF_ACCESS_KEY_SECRET, "ignored-sk"}};
    ASSERT_OK_AND_ASSIGN(std::unique_ptr<AuthProvider> provider, AuthProvider::Create(options));
    RestAuthParameter parameter = RestAuthParameter::Create("GET", "/v1/config", {}, "");
    ASSERT_OK_AND_ASSIGN(StringMap headers, provider->MergeAuthHeader({}, parameter));
    ASSERT_NE(std::string::npos, headers.at("Authorization").find("Credential=file-ak/"));

    options[CatalogOptions::DLF_TOKEN_LOADER] = "local_file";
    ASSERT_OK_AND_ASSIGN(provider, AuthProvider::Create(options));
    ASSERT_OK(provider->MergeAuthHeader({}, parameter));

    const std::string secret = "FILE_SECRET_9999";
    {
        std::ofstream file(path);
        file << R"({"AccessKeyId":"ak","AccessKeySecret":")" << secret;
    }
    Status status = loader.LoadToken().status();
    ASSERT_FALSE(status.ok());
    ASSERT_EQ(std::string::npos, status.ToString().find(secret));
}

TEST(DlfEcsTokenLoaderTest, DiscoversRoleOnceAndRefreshesToken) {
    const std::string metadata_url = "http://100.100.100.200/metadata/";
    auto http_client = std::make_unique<MockEcsHttpClient>(metadata_url);
    MockEcsHttpClient* http_client_ptr = http_client.get();
    DlfEcsTokenLoader loader(metadata_url, std::nullopt, std::move(http_client));

    ASSERT_OK_AND_ASSIGN(DlfToken first, loader.LoadToken());
    ASSERT_OK_AND_ASSIGN(DlfToken second, loader.LoadToken());
    ASSERT_EQ("ecs-ak", first.GetAccessKeyId());
    ASSERT_EQ("ecs-ak", second.GetAccessKeyId());
    ASSERT_EQ(1, http_client_ptr->GetRoleRequestCount());
    ASSERT_EQ(2, http_client_ptr->GetTokenRequestCount());
    ASSERT_EQ(180000, http_client_ptr->GetLastRequestTimeoutMillis());
}

TEST(DlfEcsTokenLoaderTest, ExplicitEmptyRoleUsesMetadataUrlAsTokenEndpoint) {
    const std::string metadata_url = "http://100.100.100.200/metadata/token";
    auto http_client = std::make_unique<MockEcsHttpClient>(metadata_url, /*direct_token=*/true);
    MockEcsHttpClient* http_client_ptr = http_client.get();
    DlfEcsTokenLoader loader(metadata_url, std::string(""), std::move(http_client));

    ASSERT_OK_AND_ASSIGN(DlfToken token, loader.LoadToken());
    ASSERT_EQ("ecs-ak", token.GetAccessKeyId());
    ASSERT_EQ(0, http_client_ptr->GetRoleRequestCount());
    ASSERT_EQ(1, http_client_ptr->GetTokenRequestCount());
    ASSERT_EQ(180000, http_client_ptr->GetLastRequestTimeoutMillis());
}

TEST(DlfEcsTokenLoaderTest, PreservesTransportFailureDetail) {
    DlfEcsTokenLoader loader("http://100.100.100.200/metadata/token", std::string(""),
                             std::make_unique<FailingEcsHttpClient>());
    Status status = loader.LoadToken().status();
    ASSERT_NOK_WITH_MSG(status, "failed to request DLF credentials from ECS metadata service");
    ASSERT_NOK_WITH_MSG(status, "connection refused");
}

TEST(DlfAuthProviderTest, RefreshesWithinSafeWindow) {
    std::atomic<int64_t> now_seconds{1744775086};
    std::vector<DlfToken> tokens;
    tokens.emplace_back("ak-1", "sk-1", std::nullopt, 1744782286000);
    tokens.emplace_back("ak-2", "sk-2", std::nullopt, std::nullopt);
    auto loader = std::make_unique<SequenceTokenLoader>(tokens);
    SequenceTokenLoader* loader_ptr = loader.get();
    ASSERT_OK_AND_ASSIGN(
        std::unique_ptr<DlfAuthProvider> provider,
        DlfAuthProvider::FromTokenLoader(
            std::move(loader), "https://cn-beijing-vpc.dlf.aliyuncs.com", "cn-beijing", "default",
            [&] { return std::chrono::system_clock::from_time_t(now_seconds.load()); }));
    RestAuthParameter parameter = RestAuthParameter::Create("GET", "/v1/config", {}, "");

    ASSERT_OK_AND_ASSIGN(StringMap first, provider->MergeAuthHeader({}, parameter));
    ASSERT_NE(std::string::npos, first.at("Authorization").find("Credential=ak-1/"));
    ASSERT_OK(provider->MergeAuthHeader({}, parameter));
    ASSERT_EQ(1, loader_ptr->GetLoadCount());

    now_seconds.fetch_add(3601);
    ASSERT_OK_AND_ASSIGN(StringMap refreshed, provider->MergeAuthHeader({}, parameter));
    ASSERT_NE(std::string::npos, refreshed.at("Authorization").find("Credential=ak-2/"));
    ASSERT_EQ(2, loader_ptr->GetLoadCount());
}

TEST(DlfAuthProviderTest, ConcurrentFirstUseLoadsTokenOnce) {
    auto loader = std::make_unique<SequenceTokenLoader>(
        std::vector<DlfToken>{
            DlfToken("concurrent-ak", "concurrent-sk", std::nullopt, std::nullopt)},
        std::chrono::milliseconds(10));
    SequenceTokenLoader* loader_ptr = loader.get();
    ASSERT_OK_AND_ASSIGN(std::unique_ptr<DlfAuthProvider> provider,
                         DlfAuthProvider::FromTokenLoader(std::move(loader),
                                                          "https://cn-beijing-vpc.dlf.aliyuncs.com",
                                                          "cn-beijing", "default", FixedTime));
    RestAuthParameter parameter = RestAuthParameter::Create("GET", "/v1/config", {}, "");
    std::vector<std::thread> threads;
    std::vector<Status> statuses;
    std::mutex statuses_mutex;
    for (int32_t i = 0; i < 16; ++i) {
        threads.emplace_back([&] {
            Status status = provider->MergeAuthHeader({}, parameter).status();
            std::scoped_lock lock(statuses_mutex);
            statuses.push_back(status);
        });
    }
    for (std::thread& thread : threads) {
        thread.join();
    }
    ASSERT_EQ(16, statuses.size());
    for (const Status& status : statuses) {
        ASSERT_OK(status);
    }
    ASSERT_EQ(1, loader_ptr->GetLoadCount());
}

TEST(DlfAuthProviderTest, SelectsEndpointSignerAndCredentialSource) {
    std::map<std::string, std::string> options = {
        {CatalogOptions::URI, "https://dlfnext.cn-hangzhou.aliyuncs.com"},
        {CatalogOptions::TOKEN_PROVIDER, "dlf"},
        {CatalogOptions::DLF_ACCESS_KEY_ID, "ak"},
        {CatalogOptions::DLF_ACCESS_KEY_SECRET, "sk"},
        {CatalogOptions::DLF_SECURITY_TOKEN, "sts"}};
    ASSERT_OK_AND_ASSIGN(std::unique_ptr<AuthProvider> provider, AuthProvider::Create(options));
    RestAuthParameter parameter = RestAuthParameter::Create("GET", "/v1/config", {}, "");
    ASSERT_OK_AND_ASSIGN(StringMap headers, provider->MergeAuthHeader({{"Authorization", "old"},
                                                                       {"x-acs-version", "old"},
                                                                       {"custom-header", "kept"}},
                                                                      parameter));
    ASSERT_NE(std::string::npos, headers.at("Authorization").find("acs ak:"));
    ASSERT_EQ("2026-01-18", headers.at("x-acs-version"));
    ASSERT_EQ("sts", headers.at("x-acs-security-token"));
    ASSERT_EQ("kept", headers.at("custom-header"));
    ASSERT_FALSE(provider->AllowsRedirects());

    BearTokenAuthProvider bear_provider("token");
    ASSERT_TRUE(bear_provider.AllowsRedirects());

    ASSERT_EQ("openapi", DlfAuthProvider::ParseSigningAlgorithmFromUri(options.at("uri")));
    ASSERT_EQ("default", DlfAuthProvider::ParseSigningAlgorithmFromUri(
                             "https://cn-hangzhou-vpc.dlf.aliyuncs.com"));
    ASSERT_OK_AND_ASSIGN(std::string region,
                         DlfAuthProvider::ParseRegionFromUri(options.at("uri")));
    ASSERT_EQ("cn-hangzhou", region);
    ASSERT_OK_AND_ASSIGN(std::string host,
                         DlfAuthProvider::ExtractHost("https://example.com:8443/prefix"));
    ASSERT_EQ("example.com:8443", host);
}

TEST(DlfAuthProviderTest, NormalizesSigningHostLikeTransport) {
    std::map<std::string, std::string> options = {
        {CatalogOptions::URI, " https://dlfnext.cn-hangzhou.aliyuncs.com "},
        {CatalogOptions::TOKEN_PROVIDER, "dlf"},
        {CatalogOptions::DLF_ACCESS_KEY_ID, "ak"},
        {CatalogOptions::DLF_ACCESS_KEY_SECRET, "sk"}};
    ASSERT_OK_AND_ASSIGN(std::unique_ptr<AuthProvider> provider, AuthProvider::Create(options));
    RestAuthParameter parameter = RestAuthParameter::Create("GET", "/v1/config", {}, "");
    ASSERT_OK_AND_ASSIGN(StringMap headers, provider->MergeAuthHeader({}, parameter));
    ASSERT_EQ("dlfnext.cn-hangzhou.aliyuncs.com", headers.at("Host"));
}

TEST(DlfAuthProviderTest, RejectsIncompleteOrUnknownConfiguration) {
    const std::map<std::string, std::string> base = {
        {CatalogOptions::URI, "https://dlfnext.cn-hangzhou.aliyuncs.com"},
        {CatalogOptions::TOKEN_PROVIDER, "dlf"}};
    ASSERT_NOK_WITH_MSG(AuthProvider::Create(base).status(), "token path or access key");

    std::map<std::string, std::string> options = base;
    options[CatalogOptions::DLF_TOKEN_LOADER] = "ecs";
    options[CatalogOptions::DLF_TOKEN_ECS_METADATA_URL] = "http://metadata/";
    options[CatalogOptions::DLF_TOKEN_ECS_ROLE_NAME] = "role";
    ASSERT_OK(AuthProvider::Create(options));

    options = base;
    options[CatalogOptions::DLF_TOKEN_LOADER] = "unknown";
    ASSERT_NOK_WITH_MSG(AuthProvider::Create(options).status(), "unsupported DLF token loader");

    options = base;
    options[CatalogOptions::DLF_ACCESS_KEY_ID] = "ak";
    options[CatalogOptions::DLF_ACCESS_KEY_SECRET] = "sk";
    options[CatalogOptions::DLF_SIGNING_ALGORITHM] = "unknown";
    ASSERT_NOK_WITH_MSG(AuthProvider::Create(options).status(),
                        "unsupported DLF signing algorithm");

    options[CatalogOptions::DLF_SIGNING_ALGORITHM] = "default";
    options[CatalogOptions::URI] = "http://127.0.0.1:8080";
    ASSERT_NOK_WITH_MSG(AuthProvider::Create(options).status(), "DLF region");
}

}  // namespace paimon::test
