// 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.

#pragma once

#include <gen_cpp/Status_types.h>

#include <cstdint>
#include <filesystem>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

namespace doris {
// Names are in lexico order.
enum class ObjStorageProvider : uint8_t {
    UNKNOWN = 0,
    AWS = 1,
    AZURE = 2,
    BOS = 3,
    COS = 4,
    OSS = 5,
    OBS = 6,
    GCP = 7,
    TOS = 8,
};

/// eg:
///     s3://bucket1/path/to/file.txt
/// path:   s3://bucket1/path/to/file.txt
/// bucket: bucket1
/// key:    path/to/file.txt
struct ObjStoragePath {
    std::filesystem::path path = "";
    std::string bucket {}; // blob container in azure
    std::string key {};    // blob name in azure
    std::string prefix {}; // for list and recursive delete
};

struct ObjStorageEndpointInfo {
    std::string endpoint {};
    std::string ak {};
    std::string sk {};
    std::string tls_debug_context {};
};

struct ObjectMeta {
    std::string key {};
    int64_t size {0};
    int64_t mtime_s {0};
};

struct ObjStorageCompletedPart {
    int part_num = 0;
    std::string etag {};
};

struct ObjStorageStatus {
    enum Code : int {
        OK = TStatusCode::OK,
        INTERNAL_ERROR = TStatusCode::INTERNAL_ERROR,
        LIMIT_REACH = TStatusCode::LIMIT_REACH,
        NOT_FOUND = TStatusCode::NOT_FOUND,
        END_OF_FILE = TStatusCode::END_OF_FILE,
        IO_ERROR = TStatusCode::IO_ERROR,
        NETWORK_ERROR = TStatusCode::NETWORK_ERROR,
        // Keep the legacy BE error code for access-denied object storage responses.
        PERMISSION_DENIED = -256,
    };

    ObjStorageStatus(int r = OK, std::string msg = "") : code(r), msg(std::move(msg)) {}
    // clang-format off
    int code {OK}; // To unify the error handle logic with BE, we'd better use the same error code as BE
    // clang-format on
    std::string msg;
};

// We only store error code along with err_msg instead of Status to unify BE and recycler's error handle logic
struct ObjStorageResponse {
    ObjStorageStatus status {ObjStorageStatus::OK, ""};
    int http_code {200};
    std::string request_id {};
    static ObjStorageResponse OK() {
        // clang-format off
        return {
                .status = ObjStorageStatus{ObjStorageStatus::OK, ""},
                .http_code = 200,
                .request_id = ""
        };
        // clang-format on
    }

    static ObjStorageResponse rate_limit(int status_code, int http_code, std::string message) {
        return {
                .status = ObjStorageStatus {status_code, std::move(message)},
                .http_code = http_code,
        };
    }

    bool ok() const { return status.code == ObjStorageStatus::OK; }
};

// Convert a provider HTTP response code into the object-storage status domain. A non-positive
// response code means that no HTTP response was received.
ObjStorageStatus obj_storage_status_from_http_code(int http_code, std::string message);

struct ObjStorageUploadResult {
    ObjStorageResponse resp = ObjStorageResponse::OK();
    std::optional<std::string> upload_id = std::nullopt;
    std::optional<std::string> etag = std::nullopt;
};

struct ObjStorageHeadResult {
    ObjStorageResponse resp = ObjStorageResponse::OK();
    long long file_size {0};
};

struct ObjStorageListResult {
    ObjStorageResponse resp = ObjStorageResponse::OK();
    std::optional<ObjectMeta> object = std::nullopt;
};

struct ObjStorageListPageResult {
    ObjStorageResponse resp = ObjStorageResponse::OK();
    std::vector<ObjectMeta> objects {};
    std::string continuation_token {};
    bool has_more = false;
};

struct ObjStorageCapabilities {
    size_t max_delete_batch = 1;
    size_t max_list_page = 1000;
};

using ObjStorageDeleteTask = std::function<ObjStorageResponse()>;

// Implementations must enqueue tasks immediately and remain reusable after wait() completes.
// Recycler implements this in cloud/src/recycler/s3_accessor.cpp; BE uses the synchronous fallback.
class ObjStorageDeleteExecutor {
public:
    virtual ~ObjStorageDeleteExecutor() = default;
    virtual ObjStorageResponse submit(ObjStorageDeleteTask task) = 0;
    virtual ObjStorageResponse wait() = 0;
};

struct ObjStorageRecursiveDeleteOptions {
    int64_t expiration_time = 0;
    size_t max_tasks_per_batch = 1;
    std::shared_ptr<ObjStorageDeleteExecutor> executor {};
};

class ObjStorageListIterator;
class RateLimitedObjStorageClient;

// Provider implementations are in common/cpp/obj-client/s3_obj_storage_client.cpp and
// common/cpp/obj-client/azure_obj_storage_client.cpp.
// Clients are shared-owned so a lazy list iterator can keep the complete decorator chain alive.
class ObjStorageClient : public std::enable_shared_from_this<ObjStorageClient> {
public:
    ObjStorageClient() = default;
    virtual ~ObjStorageClient() = default;

    ObjStorageClient(const ObjStorageClient&) = delete;
    ObjStorageClient& operator=(const ObjStorageClient&) = delete;
    // Create a multipart upload request. The returned token may be provider-issued or local and
    // identifies this writer's parts.
    // The input parameters should include the bucket and key for the object storage.
    virtual ObjStorageUploadResult create_multipart_upload(const ObjStoragePath& opts) = 0;
    // To directly upload a piece of data to object storage and generate a user-visible file.
    // You need to clearly specify the bucket and key
    virtual ObjStorageResponse put_object(const ObjStoragePath& opts, std::string_view stream) = 0;
    // Upload one part of a large object without making the object visible to users. upload_id is
    // the provider-issued or local writer token returned by create_multipart_upload.
    // Reusing the same bucket, key, upload_id, and part_num replaces that writer's staged part.
    virtual ObjStorageUploadResult upload_part(const ObjStoragePath& opts,
                                               const std::string& upload_id,
                                               std::string_view stream, int part_num) = 0;
    // Combine the parts belonging to upload_id into the key passed in opts. After this succeeds,
    // the complete object is visible in object storage.
    virtual ObjStorageResponse complete_multipart_upload(
            const ObjStoragePath& opts, const std::string& upload_id,
            const std::vector<ObjStorageCompletedPart>& completed_parts) = 0;
    // According to the passed bucket and key, it will access whether the corresponding file exists in the object storage.
    // If it exists, it will return the corresponding file size
    virtual ObjStorageHeadResult head_object(const ObjStoragePath& opts) = 0;
    // According to the bucket and key, it finds the corresponding file in the object storage
    // and starting from the offset, it reads bytes_read bytes into the buffer, with size_return recording the actual number of bytes read
    virtual ObjStorageResponse get_object(const ObjStoragePath& opts, void* buffer, size_t offset,
                                          size_t bytes_read, size_t* size_return) = 0;
    // Return a lazy iterator that fetches one provider page at a time.
    virtual std::unique_ptr<ObjStorageListIterator> list_objects(const ObjStoragePath& opts);
    // Collect all objects by consuming the lazy iterator. This preserves the eager BE API.
    // **Notice**: The files returned by this function contain the full key in object storage.
    virtual ObjStorageResponse list_objects(const ObjStoragePath& opts,
                                            std::vector<ObjectMeta>* objects);

    // According to the bucket and prefix specified by the user, it performs batch deletion based on the object names in the object array.
    virtual ObjStorageResponse delete_objects(const ObjStoragePath& opts,
                                              std::vector<std::string> objs) = 0;
    // Delete the file named key in the object storage bucket.
    virtual ObjStorageResponse delete_object(const ObjStoragePath& opts) = 0;
    virtual ObjStorageCapabilities capabilities() const = 0;
    // Return a presigned URL for users to access the object
    virtual std::string generate_presigned_url(const ObjStoragePath& opts,
                                               int64_t expiration_secs) = 0;

    // Get the objects' expiration time on the bucket
    virtual ObjStorageResponse get_lifecycle(const std::string& bucket,
                                             int64_t* expiration_days) = 0;

    // Check if the objects' versioning is on or off
    // returns 0 when versioning is on, otherwise versioning is off or check failed
    virtual ObjStorageResponse check_versioning(const std::string& bucket) = 0;

    virtual ObjStorageResponse abort_multipart_upload(const ObjStoragePath& path,
                                                      const std::string& upload_id) = 0;

protected:
    // Fetch at most one page. One call corresponds to exactly one provider request.
    virtual ObjStorageListPageResult list_objects_page(const ObjStoragePath& opts,
                                                       std::string_view continuation_token) = 0;

private:
    friend class ObjStorageListIterator;
    friend class RateLimitedObjStorageClient;
};

// A client-side iterator returned by ObjStorageClient. It requests one fixed-size page at a time.
class ObjStorageListIterator {
public:
    ObjStorageListIterator(std::shared_ptr<ObjStorageClient> client, ObjStoragePath opts)
            : client_(std::move(client)), opts_(std::move(opts)) {}

    bool is_valid() const { return is_valid_; }
    ObjStorageResponse has_next();
    ObjStorageListResult next();

private:
    std::shared_ptr<ObjStorageClient> client_;
    ObjStoragePath opts_;
    std::vector<ObjectMeta> objects_;
    size_t next_index_ = 0;
    std::string continuation_token_;
    bool has_more_ = true;
    bool is_valid_ = true;
};

// Provider-independent recursive deletion shared by concrete clients. Passing the complete client
// decorator chain keeps it alive for asynchronous delete tasks and applies policy per list page and
// delete batch.
ObjStorageResponse delete_objects_recursively(std::shared_ptr<ObjStorageClient> client,
                                              const ObjStoragePath& path,
                                              const ObjStorageRecursiveDeleteOptions& options = {});
} // namespace doris

// Keep the BE namespace spelling source-compatible while the implementation is
// shared with Recycler in `doris`.
namespace doris::io {
using ::doris::ObjStorageCapabilities;
using ::doris::ObjStorageClient;
using ::doris::ObjStorageCompletedPart;
using ::doris::ObjStorageDeleteExecutor;
using ::doris::ObjStorageDeleteTask;
using ::doris::ObjStorageEndpointInfo;
using ::doris::ObjStorageHeadResult;
using ::doris::ObjStorageListIterator;
using ::doris::ObjStorageListPageResult;
using ::doris::ObjStorageListResult;
using ::doris::ObjStoragePath;
using ::doris::ObjStorageProvider;
using ::doris::ObjStorageRecursiveDeleteOptions;
using ::doris::ObjStorageResponse;
using ::doris::ObjStorageStatus;
using ::doris::ObjStorageUploadResult;
using ::doris::ObjectMeta;
using ::doris::delete_objects_recursively;
} // namespace doris::io
