/*
 * 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/fs/s3/s3_file_system.h"

#include <gtest/gtest.h>

#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <optional>
#include <utility>
#include <vector>

#include "paimon/common/utils/string_utils.h"
#include "paimon/fs/s3/s3_file_system_factory.h"
#include "paimon/testing/utils/testharness.h"

namespace paimon::s3 {
namespace {

class MockHttpClient : public HttpClient {
 public:
    Result<HttpResponse> Execute(const HttpRequest& request,
                                 const HttpBodyConsumer& consumer) const override {
        request_ = request;
        HttpResponse response;
        response.status_code = status_code_;
        response.headers = response_headers_;
        if (!body_.empty()) {
            PAIMON_RETURN_NOT_OK(consumer(body_.data(), body_.size()));
            response.body_size = body_.size();
        }
        return response;
    }

    mutable HttpRequest request_;
    int32_t status_code_ = 200;
    HttpHeaders response_headers_;
    std::string body_;
};

class ScopedEnvironmentVariable {
 public:
    ScopedEnvironmentVariable(const char* name, std::optional<std::string> value) : name_(name) {
        const char* previous = std::getenv(name);
        if (previous != nullptr) {
            previous_ = previous;
        }
        if (value) {
            setenv(name, value->c_str(), 1);
        } else {
            unsetenv(name);
        }
    }

    ~ScopedEnvironmentVariable() {
        if (previous_) {
            setenv(name_.c_str(), previous_->c_str(), 1);
        } else {
            unsetenv(name_.c_str());
        }
    }

 private:
    std::string name_;
    std::optional<std::string> previous_;
};

std::map<std::string, std::string> StaticOptions() {
    return {{kS3AccessKeyOption, "access"},
            {kS3SecretKeyOption, "secret"},
            {kS3SessionTokenOption, "token"},
            {kS3RegionOption, "ap-northeast-2"}};
}

const std::string* FindHeader(const HttpHeaders& headers, const std::string& name) {
    std::string normalized_name = StringUtils::ToLowerCase(name);
    for (const auto& [header_name, value] : headers) {
        if (StringUtils::ToLowerCase(header_name) == normalized_name) {
            return &value;
        }
    }
    return nullptr;
}

TEST(S3ObjectStoreClientTest, TestHeadAndSigning) {
    auto http = std::make_shared<MockHttpClient>();
    http->response_headers_["content-length"] = "12";
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> client,
                         MakeS3ObjectStoreClient(StaticOptions(), http));
    ASSERT_OK_AND_ASSIGN(auto metadata, client->HeadObject({"bucket", "a b/file"}));
    ASSERT_EQ(metadata.size, 12);
    ASSERT_EQ(http->request_.url, "https://bucket.s3.ap-northeast-2.amazonaws.com/a%20b/file");
    const std::string* authorization = FindHeader(http->request_.headers, "authorization");
    ASSERT_NE(authorization, nullptr);
    ASSERT_NE(authorization->find("/ap-northeast-2/s3/aws4_request"), std::string::npos);
    ASSERT_NE(authorization->find(
                  "SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token"),
              std::string::npos);
    ASSERT_EQ(http->request_.headers["host"], "bucket.s3.ap-northeast-2.amazonaws.com");
    const std::string* session_token = FindHeader(http->request_.headers, "x-amz-security-token");
    ASSERT_NE(session_token, nullptr);
    ASSERT_EQ(*session_token, "token");
}

TEST(S3ObjectStoreClientTest, TestDottedBucketUsesPathStyleForDefaultEndpoint) {
    auto http = std::make_shared<MockHttpClient>();
    http->response_headers_["content-length"] = "12";
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> client,
                         MakeS3ObjectStoreClient(StaticOptions(), http));
    ASSERT_OK(client->HeadObject({"paimon.prod.data", "file"}));
    ASSERT_EQ(http->request_.url, "https://s3.ap-northeast-2.amazonaws.com/paimon.prod.data/file");
    ASSERT_EQ(http->request_.headers["host"], "s3.ap-northeast-2.amazonaws.com");

    auto path_style_options = StaticOptions();
    path_style_options[kS3PathStyleAccessOption] = "false";
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> path_style_client,
                         MakeS3ObjectStoreClient(path_style_options, http));
    ASSERT_OK(path_style_client->HeadObject({"paimon.prod.data", "file"}));
    ASSERT_EQ(http->request_.url, "https://s3.ap-northeast-2.amazonaws.com/paimon.prod.data/file");
}

TEST(S3ObjectStoreClientTest, TestCustomEndpointAddressing) {
    auto http = std::make_shared<MockHttpClient>();
    http->response_headers_["content-length"] = "12";

    auto https_options = StaticOptions();
    https_options[kS3EndpointOption] = "https://s3.example.com";
    https_options[kS3PathStyleAccessOption] = "false";
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> https_client,
                         MakeS3ObjectStoreClient(https_options, http));
    ASSERT_OK(https_client->HeadObject({"bucket", "file"}));
    ASSERT_EQ(http->request_.url, "https://s3.example.com/bucket/file");
    ASSERT_OK(https_client->HeadObject({"paimon.prod.data", "file"}));
    ASSERT_EQ(http->request_.url, "https://s3.example.com/paimon.prod.data/file");

    auto http_options = StaticOptions();
    http_options[kS3EndpointOption] = "http://s3.example.com";
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> http_client,
                         MakeS3ObjectStoreClient(http_options, http));
    ASSERT_OK(http_client->HeadObject({"paimon.prod.data", "file"}));
    ASSERT_EQ(http->request_.url, "http://paimon.prod.data.s3.example.com/file");

    auto ip_options = StaticOptions();
    ip_options[kS3EndpointOption] = "http://127.0.0.1:9000";
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> ip_client,
                         MakeS3ObjectStoreClient(ip_options, http));
    ASSERT_OK(ip_client->HeadObject({"bucket", "file"}));
    ASSERT_EQ(http->request_.url, "http://127.0.0.1:9000/bucket/file");

    auto base_path_options = StaticOptions();
    base_path_options[kS3EndpointOption] = "HTTPS://s3.example.com/storage";
    base_path_options[kS3PathStyleAccessOption] = "true";
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> base_path_client,
                         MakeS3ObjectStoreClient(base_path_options, http));
    ASSERT_OK(base_path_client->HeadObject({"bucket", "file"}));
    ASSERT_EQ(http->request_.url, "https://s3.example.com/storage/bucket/file");
}

TEST(S3ObjectStoreClientTest, TestInvalidCustomEndpoint) {
    for (const char* endpoint :
         {"ftp://s3.example.com", "https://user@s3.example.com", "https://s3.example.com?query",
          "https://s3.example.com#fragment"}) {
        auto options = StaticOptions();
        options[kS3EndpointOption] = endpoint;
        ASSERT_NOK(MakeS3ObjectStoreClient(options, std::make_shared<MockHttpClient>()));
    }
}

TEST(S3ObjectStoreClientTest, TestNonVirtualHostableBucketUsesPathStyle) {
    auto http = std::make_shared<MockHttpClient>();
    http->response_headers_["content-length"] = "12";
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> client,
                         MakeS3ObjectStoreClient(StaticOptions(), http));
    ASSERT_OK(client->HeadObject({"aa", "file"}));
    ASSERT_EQ(http->request_.url, "https://s3.ap-northeast-2.amazonaws.com/aa/file");

    auto options = StaticOptions();
    options[kS3EndpointOption] = "http://s3.example.com";
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> custom_client,
                         MakeS3ObjectStoreClient(options, http));
    ASSERT_OK(custom_client->HeadObject({"BucketName", "file"}));
    ASSERT_EQ(http->request_.url, "http://s3.example.com/BucketName/file");
}

TEST(S3ObjectStoreClientTest, TestPathStyleOptionUsesCommonBooleanParser) {
    for (const auto& [value, path_style] :
         std::vector<std::pair<std::string, bool>>{{"t", true},
                                                   {"y", true},
                                                   {"yes", true},
                                                   {"1", true},
                                                   {"f", false},
                                                   {"n", false},
                                                   {"no", false},
                                                   {"0", false}}) {
        auto options = StaticOptions();
        options[kS3PathStyleAccessOption] = value;
        auto http = std::make_shared<MockHttpClient>();
        http->response_headers_["content-length"] = "12";
        ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> client,
                             MakeS3ObjectStoreClient(options, http));
        ASSERT_OK(client->HeadObject({"bucket", "file"}));
        ASSERT_EQ(http->request_.url, path_style
                                          ? "https://s3.ap-northeast-2.amazonaws.com/bucket/file"
                                          : "https://bucket.s3.ap-northeast-2.amazonaws.com/file");
    }
}

TEST(S3ObjectStoreClientTest, TestOptionAliases) {
    auto http = std::make_shared<MockHttpClient>();
    http->response_headers_["content-length"] = "12";
    std::map<std::string, std::string> python_options{
        {"fs.s3.accessKeyId", "python-access"},  {"fs.s3.accessKeySecret", "python-secret"},
        {"fs.s3.securityToken", "python-token"}, {"fs.s3.endpoint", "http://s3.example.com"},
        {"fs.s3.region", "us-west-2"},           {"fs.s3.path.style.access", "true"}};
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> python_client,
                         MakeS3ObjectStoreClient(python_options, http));
    ASSERT_OK(python_client->HeadObject({"bucket", "file"}));
    ASSERT_EQ(http->request_.url, "http://s3.example.com/bucket/file");
    const std::string* authorization = FindHeader(http->request_.headers, "authorization");
    ASSERT_NE(authorization, nullptr);
    ASSERT_NE(authorization->find("Credential=python-access/"), std::string::npos);
    const std::string* token = FindHeader(http->request_.headers, "x-amz-security-token");
    ASSERT_NE(token, nullptr);
    ASSERT_EQ(*token, "python-token");

    std::map<std::string, std::string> java_options{{"s3a.access.key", "java-access"},
                                                    {"s3a.secret.key", "java-secret"},
                                                    {"s3a.session.token", "java-token"},
                                                    {"s3a.region", "eu-west-1"}};
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> java_client,
                         MakeS3ObjectStoreClient(java_options, http));
    ASSERT_OK(java_client->HeadObject({"bucket", "file"}));
    ASSERT_EQ(http->request_.url, "https://bucket.s3.eu-west-1.amazonaws.com/file");
    authorization = FindHeader(http->request_.headers, "authorization");
    ASSERT_NE(authorization, nullptr);
    ASSERT_NE(authorization->find("Credential=java-access/"), std::string::npos);
    token = FindHeader(http->request_.headers, "x-amz-security-token");
    ASSERT_NE(token, nullptr);
    ASSERT_EQ(*token, "java-token");
}

TEST(S3ObjectStoreClientTest, TestCanonicalOptionsTakePrecedenceOverAliases) {
    auto http = std::make_shared<MockHttpClient>();
    http->response_headers_["content-length"] = "12";
    std::map<std::string, std::string> options{{kS3AccessKeyOption, "canonical-access"},
                                               {kS3SecretKeyOption, "canonical-secret"},
                                               {"s3a.access.key", "alias-access"},
                                               {"s3a.secret.key", "alias-secret"},
                                               {kS3RegionOption, "ap-northeast-2"}};
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> client,
                         MakeS3ObjectStoreClient(options, http));
    ASSERT_OK(client->HeadObject({"bucket", "file"}));
    const std::string* authorization = FindHeader(http->request_.headers, "authorization");
    ASSERT_NE(authorization, nullptr);
    ASSERT_NE(authorization->find("Credential=canonical-access/"), std::string::npos);
}

TEST(S3ObjectStoreClientTest, TestInvalidContentLength) {
    for (const std::string content_length :
         {"", "invalid", "-1", "12abc", "999999999999999999999999"}) {
        auto http = std::make_shared<MockHttpClient>();
        http->response_headers_["content-length"] = content_length;
        ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> client,
                             MakeS3ObjectStoreClient(StaticOptions(), http));
        ASSERT_TRUE(client->HeadObject({"bucket", "file"}).status().IsIOError());
    }
}

TEST(S3ObjectStoreClientTest, TestInvalidModificationTime) {
    auto http = std::make_shared<MockHttpClient>();
    http->response_headers_["content-length"] = "12";
    http->response_headers_["last-modified"] = "invalid";
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> client,
                         MakeS3ObjectStoreClient(StaticOptions(), http));
    ASSERT_OK_AND_ASSIGN(auto metadata, client->HeadObject({"bucket", "file"}));
    ASSERT_EQ(metadata.modification_time, 0);

    http->body_ =
        "<ListBucketResult><IsTruncated>false</IsTruncated><Contents><Key>file</Key>"
        "<LastModified>invalid</LastModified><Size>12</Size></Contents></ListBucketResult>";
    ASSERT_OK_AND_ASSIGN(auto result, client->ListObjects({"bucket", ""}, "", 0));
    ASSERT_EQ(result.objects[0].modification_time, 0);
}

TEST(S3ObjectStoreClientTest, TestRegionFromEnvironment) {
    ScopedEnvironmentVariable region("AWS_REGION", "eu-west-1");
    auto options = StaticOptions();
    options.erase(kS3RegionOption);
    auto http = std::make_shared<MockHttpClient>();
    http->response_headers_["content-length"] = "12";
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> client,
                         MakeS3ObjectStoreClient(options, http));
    ASSERT_OK(client->HeadObject({"bucket", "file"}));
    ASSERT_EQ(http->request_.url, "https://bucket.s3.eu-west-1.amazonaws.com/file");
}

TEST(S3ObjectStoreClientTest, TestDefaultEndpointsForAwsPartitions) {
    for (const auto& [region, endpoint] : std::vector<std::pair<std::string, std::string>>{
             {"ap-northeast-2", "https://bucket.s3.ap-northeast-2.amazonaws.com/file"},
             {"cn-north-1", "https://bucket.s3.cn-north-1.amazonaws.com.cn/file"},
             {"eusc-de-east-1", "https://bucket.s3.eusc-de-east-1.amazonaws.eu/file"},
             {"us-iso-east-1", "https://bucket.s3.us-iso-east-1.c2s.ic.gov/file"},
             {"us-isob-east-1", "https://bucket.s3.us-isob-east-1.sc2s.sgov.gov/file"},
             {"eu-isoe-west-1", "https://bucket.s3.eu-isoe-west-1.cloud.adc-e.uk/file"},
             {"us-isof-south-1", "https://bucket.s3.us-isof-south-1.csp.hci.ic.gov/file"},
             {"us-gov-west-1", "https://bucket.s3.us-gov-west-1.amazonaws.com/file"}}) {
        auto options = StaticOptions();
        options[kS3RegionOption] = region;
        auto http = std::make_shared<MockHttpClient>();
        http->response_headers_["content-length"] = "12";
        ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> client,
                             MakeS3ObjectStoreClient(options, http));
        ASSERT_OK(client->HeadObject({"bucket", "file"}));
        ASSERT_EQ(http->request_.url, endpoint);
    }
}

TEST(S3ObjectStoreClientTest, TestRegionFromProfile) {
    auto test_dir = paimon::test::UniqueTestDirectory::Create();
    ASSERT_TRUE(test_dir);
    std::filesystem::path config_path = std::filesystem::path(test_dir->Str()) / "region-config";
    {
        std::ofstream config(config_path);
        config << "[profile test-profile]\nregion = ap-south-1\n";
    }
    ScopedEnvironmentVariable region("AWS_REGION", std::nullopt);
    ScopedEnvironmentVariable default_region("AWS_DEFAULT_REGION", std::nullopt);
    ScopedEnvironmentVariable config_file("AWS_CONFIG_FILE", config_path.string());
    auto options = StaticOptions();
    options.erase(kS3RegionOption);
    options[kS3ProfileOption] = "test-profile";
    auto http = std::make_shared<MockHttpClient>();
    http->response_headers_["content-length"] = "12";
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> client,
                         MakeS3ObjectStoreClient(options, http));
    ASSERT_OK(client->HeadObject({"bucket", "file"}));
    ASSERT_EQ(http->request_.url, "https://bucket.s3.ap-south-1.amazonaws.com/file");
}

TEST(S3ObjectStoreClientTest, TestCredentialsFromEnvironmentProfile) {
    auto test_dir = paimon::test::UniqueTestDirectory::Create();
    ASSERT_TRUE(test_dir);
    std::filesystem::path credentials_path =
        std::filesystem::path(test_dir->Str()) / "credentials-config";
    {
        std::ofstream credentials(credentials_path);
        credentials << "[environment-profile]\n"
                       "aws_access_key_id = profile-access\n"
                       "aws_secret_access_key = profile-secret\n"
                       "aws_session_token = profile-token\n"
                       "[default]\n"
                       "aws_access_key_id = default-access\n"
                       "aws_secret_access_key = default-secret\n"
                       "aws_session_token = default-token\n";
    }
    ScopedEnvironmentVariable credentials_file("AWS_SHARED_CREDENTIALS_FILE",
                                               credentials_path.string());
    ScopedEnvironmentVariable access_key("AWS_ACCESS_KEY_ID", std::nullopt);
    ScopedEnvironmentVariable secret_key("AWS_SECRET_ACCESS_KEY", std::nullopt);
    ScopedEnvironmentVariable session_token("AWS_SESSION_TOKEN", std::nullopt);
    {
        ScopedEnvironmentVariable profile("AWS_PROFILE", "environment-profile");
        auto http = std::make_shared<MockHttpClient>();
        http->response_headers_["content-length"] = "12";
        ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> client,
                             MakeS3ObjectStoreClient({{kS3RegionOption, "ap-northeast-2"}}, http));
        ASSERT_OK(client->HeadObject({"bucket", "file"}));
        const std::string* authorization = FindHeader(http->request_.headers, "authorization");
        ASSERT_NE(authorization, nullptr);
        ASSERT_NE(authorization->find("Credential=profile-access/"), std::string::npos);
        const std::string* token = FindHeader(http->request_.headers, "x-amz-security-token");
        ASSERT_NE(token, nullptr);
        ASSERT_EQ(*token, "profile-token");
    }
    {
        ScopedEnvironmentVariable profile("AWS_PROFILE", std::nullopt);
        auto http = std::make_shared<MockHttpClient>();
        http->response_headers_["content-length"] = "12";
        ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> client,
                             MakeS3ObjectStoreClient({{kS3RegionOption, "ap-northeast-2"}}, http));
        ASSERT_OK(client->HeadObject({"bucket", "file"}));
        const std::string* authorization = FindHeader(http->request_.headers, "authorization");
        ASSERT_NE(authorization, nullptr);
        ASSERT_NE(authorization->find("Credential=default-access/"), std::string::npos);
        const std::string* token = FindHeader(http->request_.headers, "x-amz-security-token");
        ASSERT_NE(token, nullptr);
        ASSERT_EQ(*token, "default-token");
    }
}

TEST(S3ObjectStoreClientTest, TestRangeAndListObjects) {
    auto http = std::make_shared<MockHttpClient>();
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> client,
                         MakeS3ObjectStoreClient(StaticOptions(), http));
    http->body_ = "data";
    char buffer[4];
    ASSERT_OK_AND_ASSIGN(auto size, client->GetObjectRange({"bucket", "key"}, 2, 4, buffer));
    ASSERT_EQ(size, 4);
    ASSERT_EQ(std::string(buffer, sizeof(buffer)), "data");
    ASSERT_EQ(http->request_.headers["range"], "bytes=2-5");

    http->body_ =
        "<ListBucketResult><IsTruncated>true</IsTruncated>"
        "<Contents><Key>dir/a&amp;b</Key><LastModified>2026-01-01T00:00:00Z</LastModified>"
        "<Size>7</Size></Contents><Contents><Key>dir/a&amp;lt;b</Key><Size>8</Size></Contents>"
        "<CommonPrefixes><Prefix>dir/sub/</Prefix></CommonPrefixes>"
        "<NextContinuationToken>next token</NextContinuationToken></ListBucketResult>";
    ASSERT_OK_AND_ASSIGN(auto result, client->ListObjects({"bucket", "dir/"}, "old token", 10));
    ASSERT_TRUE(result.is_truncated);
    ASSERT_EQ(result.continuation_token, "next token");
    ASSERT_EQ(result.objects[0].key, "dir/a&b");
    ASSERT_EQ(result.objects[1].key, "dir/a&lt;b");
    ASSERT_EQ(result.common_prefixes[0], "dir/sub/");
    ASSERT_NE(http->request_.url.find("amazonaws.com/?list-type=2"), std::string::npos);
    ASSERT_NE(http->request_.url.find("encoding-type=url"), std::string::npos);
    ASSERT_NE(http->request_.url.find("continuation-token=old%20token"), std::string::npos);
}

TEST(S3ObjectStoreClientTest, TestUrlEncodedListObjects) {
    auto http = std::make_shared<MockHttpClient>();
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> client,
                         MakeS3ObjectStoreClient(StaticOptions(), http));
    http->body_ =
        "<ListBucketResult><IsTruncated>true</IsTruncated>"
        "<Contents><Key>dir/a%26b%0D</Key><Size>7</Size></Contents>"
        "<CommonPrefixes><Prefix>dir/sub%25/</Prefix></CommonPrefixes>"
        "<NextContinuationToken>next%2Ftoken</NextContinuationToken></ListBucketResult>";
    ASSERT_OK_AND_ASSIGN(auto result, client->ListObjects({"bucket", "dir/"}, "", 0));
    ASSERT_EQ(result.objects[0].key, "dir/a&b\r");
    ASSERT_EQ(result.common_prefixes[0], "dir/sub%/");
    ASSERT_EQ(result.continuation_token, "next%2Ftoken");

    http->body_ = "<ListBucketResult><IsTruncated>false</IsTruncated></ListBucketResult>";
    ASSERT_OK(client->ListObjects({"bucket", "dir/"}, result.continuation_token, 0));
    ASSERT_NE(http->request_.url.find("continuation-token=next%252Ftoken"), std::string::npos);

    http->body_ =
        "<ListBucketResult><IsTruncated>false</IsTruncated>"
        "<Contents><Key>dir/invalid%2</Key><Size>7</Size></Contents></ListBucketResult>";
    ASSERT_TRUE(client->ListObjects({"bucket", "dir/"}, "", 0).status().IsIOError());
}

TEST(S3ObjectStoreClientTest, TestInvalidListObjectsResponse) {
    auto http = std::make_shared<MockHttpClient>();
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<ObjectStoreClient> client,
                         MakeS3ObjectStoreClient(StaticOptions(), http));
    for (const std::string size : {"", "abc", "-1", "12abc", "9223372036854775808"}) {
        http->body_ =
            "<ListBucketResult><IsTruncated>false</IsTruncated><Contents><Key>key</Key>"
            "<Size>" +
            size + "</Size></Contents></ListBucketResult>";
        ASSERT_TRUE(client->ListObjects({"bucket", ""}, "", 0).status().IsIOError());
    }
    http->body_ =
        "<ListBucketResult><IsTruncated>false</IsTruncated><Contents><Key>key</Key>"
        "<Size>1</Size></ListBucketResult>";
    ASSERT_TRUE(client->ListObjects({"bucket", ""}, "", 0).status().IsIOError());
    http->body_ =
        "<ListBucketResult><Contents><Key>key</Key><Size>1</Size></Contents></ListBucketResult>";
    ASSERT_TRUE(client->ListObjects({"bucket", ""}, "", 0).status().IsIOError());
}

TEST(S3FileSystemFactoryTest, TestOptionValidation) {
    S3FileSystemFactory factory;
    ASSERT_TRUE(
        factory.Create("s3://bucket", {{kS3AccessKeyOption, ""}, {kS3SecretKeyOption, "secret"}})
            .status()
            .IsInvalid());
    ASSERT_TRUE(
        factory.Create("s3://bucket", {{kS3PathStyleAccessOption, "treu"}}).status().IsInvalid());
    ASSERT_TRUE(
        factory.Create("s3://bucket", {{kS3PathStyleAccessOption, "on"}}).status().IsInvalid());
    ASSERT_TRUE(
        factory.Create("s3://bucket", {{kS3SessionTokenOption, "token"}}).status().IsInvalid());

    auto http = std::make_shared<MockHttpClient>();
    ASSERT_TRUE(
        MakeS3ObjectStoreClient({{kS3AccessKeyOption, "access"}}, http).status().IsInvalid());
    ASSERT_TRUE(
        MakeS3ObjectStoreClient({{kS3PathStyleAccessOption, "treu"}}, http).status().IsInvalid());
}

}  // namespace
}  // namespace paimon::s3
