#ifndef TRANSTUI_TORRENT_H
#define TRANSTUI_TORRENT_H

#include <stddef.h>
#include <stdint.h>
#include "rpc.h"

enum {
    TR_STATUS_STOPPED = 0,
    TR_STATUS_CHECK_WAIT = 1,
    TR_STATUS_CHECK = 2,
    TR_STATUS_DOWNLOAD_WAIT = 3,
    TR_STATUS_DOWNLOAD = 4,
    TR_STATUS_SEED_WAIT = 5,
    TR_STATUS_SEED = 6,
};

typedef struct {
    int id;
    char hash[41];
    char name[256];
    int64_t total_size;
    int64_t left_until_done;
    double percent_done;
    int status;
    int64_t rate_download;
    int64_t rate_upload;
    int eta;
    double upload_ratio;
    int error;
    char error_string[256];
    char download_dir[512];
    int peers_connected;
    int peers_sending_to_us;
    int peers_getting_from_us;
    int selected; /* multi-select flag, UI-owned */
} Torrent;

typedef struct {
    Torrent *items;
    size_t count;
    size_t capacity;
} TorrentList;

typedef struct {
    char name[512];
    int64_t length;
    int64_t bytes_completed;
    int wanted;
    int priority; /* -1 low, 0 normal, 1 high */
} TorrentFile;

typedef struct {
    char address[64];
    char client_name[128];
    double progress;
    int64_t rate_to_client;
    int64_t rate_to_peer;
    char flags[16];
} TorrentPeer;

typedef struct {
    char announce[256];
    int tier;
    char last_announce_result[256];
    int seeder_count;
    int leecher_count;
} TorrentTracker;

typedef struct {
    Torrent info;
    long date_added;
    long date_created;
    long done_date;
    int64_t download_limit;
    int download_limited;
    int64_t upload_limit;
    int upload_limited;

    TorrentFile *files;
    size_t file_count;
    TorrentPeer *peers;
    size_t peer_count;
    TorrentTracker *trackers;
    size_t tracker_count;
} TorrentDetail;

void torrent_list_init(TorrentList *list);
void torrent_list_free(TorrentList *list);
/* Fetches the summary field set for all torrents and refreshes `list` in
 * place, reusing the existing allocation where possible. */
int torrent_list_refresh(RpcClient *rpc, TorrentList *list, char *err, size_t errlen);

void torrent_detail_free(TorrentDetail *d);
int torrent_get_detail(RpcClient *rpc, int id, TorrentDetail *out, char *err, size_t errlen);

/* method is one of: torrent-start, torrent-start-now, torrent-stop,
 * torrent-verify, torrent-reannounce */
int torrent_action(RpcClient *rpc, const char *method, const int *ids, size_t n, char *err, size_t errlen);
int torrent_remove(RpcClient *rpc, const int *ids, size_t n, int delete_data, char *err, size_t errlen);

/* source: a magnet: URI, an http(s):// URL to a .torrent, or a local file
 * path (read and sent as base64 metainfo, so it works against remote daemons
 * too). download_dir may be NULL to use the daemon's default. */
int torrent_add(RpcClient *rpc, const char *source, const char *download_dir, char *err, size_t errlen);

int torrent_set_speed_limit(RpcClient *rpc, const int *ids, size_t n,
                             int64_t down_kbps, int down_enabled,
                             int64_t up_kbps, int up_enabled,
                             char *err, size_t errlen);

int torrent_set_file_wanted(RpcClient *rpc, int id, const int *file_indices, size_t n, int wanted,
                             char *err, size_t errlen);
int torrent_set_file_priority(RpcClient *rpc, int id, const int *file_indices, size_t n, int priority,
                               char *err, size_t errlen);

#endif
