/**
 * @file storage.h
 * @brief Synor Storage SDK for C
 *
 * Provides IPFS-compatible decentralized storage with upload, download,
 * pinning, and CAR file operations.
 */

#ifndef SYNOR_STORAGE_H
#define SYNOR_STORAGE_H

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "wallet.h"  /* For synor_error_t */

#ifdef __cplusplus
extern "C" {
#endif

/* Pin status */
typedef enum {
    SYNOR_PIN_STATUS_QUEUED = 0,
    SYNOR_PIN_STATUS_PINNING,
    SYNOR_PIN_STATUS_PINNED,
    SYNOR_PIN_STATUS_FAILED,
    SYNOR_PIN_STATUS_UNPINNED
} synor_pin_status_t;

/* Hash algorithm */
typedef enum {
    SYNOR_HASH_SHA2_256 = 0,
    SYNOR_HASH_BLAKE3
} synor_hash_algorithm_t;

/* Entry type */
typedef enum {
    SYNOR_ENTRY_FILE = 0,
    SYNOR_ENTRY_DIRECTORY
} synor_entry_type_t;

/* Storage configuration */
typedef struct {
    const char* api_key;
    const char* endpoint;   /* Default: "https://storage.synor.io/v1" */
    const char* gateway;    /* Default: "https://gateway.synor.io" */
    uint32_t timeout_ms;    /* Default: 60000 */
    uint32_t retries;       /* Default: 3 */
    bool debug;             /* Default: false */
} synor_storage_config_t;

/* Opaque storage client handle */
typedef struct synor_storage synor_storage_t;

/* Upload options */
typedef struct {
    const char* name;           /* May be NULL */
    bool wrap_with_directory;   /* Default: false */
    synor_hash_algorithm_t hash_algorithm;  /* Default: SHA2_256 */
    int32_t chunk_size;         /* 0 for default */
    int32_t pin_duration_days;  /* 0 for default */
} synor_upload_options_t;

/* Upload response */
typedef struct {
    char* cid;
    int64_t size;
    char* name;        /* May be NULL */
    char* created_at;
} synor_upload_response_t;

/* Pin info */
typedef struct {
    char* cid;
    char* name;        /* May be NULL */
    synor_pin_status_t status;
    int64_t size;
    char* created_at;
    char* expires_at;  /* May be NULL */
    char** delegates;
    size_t delegate_count;
} synor_pin_t;

/* Pin request */
typedef struct {
    const char* cid;
    const char* name;       /* May be NULL */
    int32_t duration_days;  /* 0 for default */
    const char** origins;
    size_t origin_count;
} synor_pin_request_t;

/* Pin list */
typedef struct {
    synor_pin_t* pins;
    size_t count;
} synor_pin_list_t;

/* CAR file info */
typedef struct {
    char* cid;
    int64_t size;
    char** roots;
    size_t root_count;
    char* created_at;
} synor_car_file_t;

/* File entry for upload */
typedef struct {
    const char* path;
    const uint8_t* content;
    size_t content_size;
} synor_file_entry_t;

/* Directory entry */
typedef struct {
    char* name;
    char* cid;
    int64_t size;
    synor_entry_type_t type;
} synor_directory_entry_t;

/* Directory listing */
typedef struct {
    synor_directory_entry_t* entries;
    size_t count;
} synor_directory_listing_t;

/* Storage statistics */
typedef struct {
    int64_t total_size;
    int32_t pin_count;
    int64_t bandwidth_used;
    double quota_used;
} synor_storage_stats_t;

/* CID list (for CAR import) */
typedef struct {
    char** cids;
    size_t count;
} synor_cid_list_t;

/* Download callback for streaming */
typedef void (*synor_download_callback_t)(
    const uint8_t* data,
    size_t size,
    void* user_data
);

/**
 * Create a new storage client.
 */
synor_storage_t* synor_storage_create(const synor_storage_config_t* config);

/**
 * Destroy storage client and free resources.
 */
void synor_storage_destroy(synor_storage_t* storage);

/* Upload operations */

synor_error_t synor_storage_upload(
    synor_storage_t* storage,
    const uint8_t* data,
    size_t size,
    const synor_upload_options_t* options,
    synor_upload_response_t* result
);

synor_error_t synor_storage_upload_directory(
    synor_storage_t* storage,
    const synor_file_entry_t* files,
    size_t file_count,
    const char* dir_name,
    synor_upload_response_t* result
);

/* Download operations */

synor_error_t synor_storage_download(
    synor_storage_t* storage,
    const char* cid,
    uint8_t** data,
    size_t* size
);

synor_error_t synor_storage_download_stream(
    synor_storage_t* storage,
    const char* cid,
    synor_download_callback_t callback,
    void* user_data
);

/**
 * Get gateway URL for content.
 * Caller must free the returned string.
 */
char* synor_storage_get_gateway_url(
    synor_storage_t* storage,
    const char* cid,
    const char* path  /* May be NULL */
);

/* Pinning operations */

synor_error_t synor_storage_pin(
    synor_storage_t* storage,
    const synor_pin_request_t* request,
    synor_pin_t* result
);

synor_error_t synor_storage_unpin(
    synor_storage_t* storage,
    const char* cid
);

synor_error_t synor_storage_get_pin_status(
    synor_storage_t* storage,
    const char* cid,
    synor_pin_t* result
);

synor_error_t synor_storage_list_pins(
    synor_storage_t* storage,
    synor_pin_status_t* status,  /* NULL for all */
    int32_t limit,
    int32_t offset,
    synor_pin_list_t* result
);

/* CAR file operations */

synor_error_t synor_storage_create_car(
    synor_storage_t* storage,
    const synor_file_entry_t* entries,
    size_t entry_count,
    synor_car_file_t* result
);

synor_error_t synor_storage_import_car(
    synor_storage_t* storage,
    const uint8_t* car_data,
    size_t car_size,
    synor_cid_list_t* result
);

synor_error_t synor_storage_export_car(
    synor_storage_t* storage,
    const char* cid,
    uint8_t** data,
    size_t* size
);

/* Directory operations */

synor_error_t synor_storage_list_directory(
    synor_storage_t* storage,
    const char* cid,
    synor_directory_listing_t* result
);

/* Statistics */

synor_error_t synor_storage_get_stats(
    synor_storage_t* storage,
    synor_storage_stats_t* result
);

/* Free functions */
void synor_upload_response_free(synor_upload_response_t* response);
void synor_pin_free(synor_pin_t* pin);
void synor_pin_list_free(synor_pin_list_t* list);
void synor_car_file_free(synor_car_file_t* car);
void synor_cid_list_free(synor_cid_list_t* list);
void synor_directory_entry_free(synor_directory_entry_t* entry);
void synor_directory_listing_free(synor_directory_listing_t* listing);

#ifdef __cplusplus
}
#endif

#endif /* SYNOR_STORAGE_H */
