// This file Copyright © 2013-2023 Mnemosyne LLC.
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
// or any future license endorsed by Mnemosyne LLC.
// License text can be found in the licenses/ folder.

#include <algorithm>
#include <array>
#include <string>
#include <string_view>
#include <vector>

#include "transmission.h"

#include "quark.h"

using namespace std::literals;

namespace
{

auto constexpr MyStatic = std::array<std::string_view, 401>{ ""sv,
                                                             "activeTorrentCount"sv,
                                                             "activity-date"sv,
                                                             "activityDate"sv,
                                                             "added"sv,
                                                             "added-date"sv,
                                                             "added.f"sv,
                                                             "added6"sv,
                                                             "added6.f"sv,
                                                             "addedDate"sv,
                                                             "address"sv,
                                                             "alt-speed-down"sv,
                                                             "alt-speed-enabled"sv,
                                                             "alt-speed-time-begin"sv,
                                                             "alt-speed-time-day"sv,
                                                             "alt-speed-time-enabled"sv,
                                                             "alt-speed-time-end"sv,
                                                             "alt-speed-up"sv,
                                                             "announce"sv,
                                                             "announce-ip"sv,
                                                             "announce-ip-enabled"sv,
                                                             "announce-list"sv,
                                                             "announceState"sv,
                                                             "anti-brute-force-enabled"sv,
                                                             "anti-brute-force-threshold"sv,
                                                             "arguments"sv,
                                                             "availability"sv,
                                                             "bandwidth-priority"sv,
                                                             "bandwidthPriority"sv,
                                                             "bind-address-ipv4"sv,
                                                             "bind-address-ipv6"sv,
                                                             "bitfield"sv,
                                                             "blocklist-date"sv,
                                                             "blocklist-enabled"sv,
                                                             "blocklist-size"sv,
                                                             "blocklist-updates-enabled"sv,
                                                             "blocklist-url"sv,
                                                             "blocks"sv,
                                                             "bytesCompleted"sv,
                                                             "cache-size-mb"sv,
                                                             "clientIsChoked"sv,
                                                             "clientIsInterested"sv,
                                                             "clientName"sv,
                                                             "comment"sv,
                                                             "comment_utf_8"sv,
                                                             "compact-view"sv,
                                                             "complete"sv,
                                                             "config-dir"sv,
                                                             "cookies"sv,
                                                             "corrupt"sv,
                                                             "corruptEver"sv,
                                                             "created by"sv,
                                                             "created by.utf-8"sv,
                                                             "creation date"sv,
                                                             "creator"sv,
                                                             "cumulative-stats"sv,
                                                             "current-stats"sv,
                                                             "date"sv,
                                                             "dateCreated"sv,
                                                             "default-trackers"sv,
                                                             "delete-local-data"sv,
                                                             "desiredAvailable"sv,
                                                             "destination"sv,
                                                             "details-window-height"sv,
                                                             "details-window-width"sv,
                                                             "dht-enabled"sv,
                                                             "dnd"sv,
                                                             "done-date"sv,
                                                             "doneDate"sv,
                                                             "download-dir"sv,
                                                             "download-dir-free-space"sv,
                                                             "download-queue-enabled"sv,
                                                             "download-queue-size"sv,
                                                             "downloadCount"sv,
                                                             "downloadDir"sv,
                                                             "downloadLimit"sv,
                                                             "downloadLimited"sv,
                                                             "downloadSpeed"sv,
                                                             "downloaded"sv,
                                                             "downloaded-bytes"sv,
                                                             "downloadedBytes"sv,
                                                             "downloadedEver"sv,
                                                             "downloaders"sv,
                                                             "downloading-time-seconds"sv,
                                                             "dropped"sv,
                                                             "dropped6"sv,
                                                             "e"sv,
                                                             "editDate"sv,
                                                             "encoding"sv,
                                                             "encryption"sv,
                                                             "error"sv,
                                                             "errorString"sv,
                                                             "eta"sv,
                                                             "etaIdle"sv,
                                                             "fields"sv,
                                                             "file-count"sv,
                                                             "fileStats"sv,
                                                             "filename"sv,
                                                             "files"sv,
                                                             "files-added"sv,
                                                             "files-unwanted"sv,
                                                             "files-wanted"sv,
                                                             "filesAdded"sv,
                                                             "filter-mode"sv,
                                                             "filter-text"sv,
                                                             "filter-trackers"sv,
                                                             "flagStr"sv,
                                                             "flags"sv,
                                                             "format"sv,
                                                             "fromCache"sv,
                                                             "fromDht"sv,
                                                             "fromIncoming"sv,
                                                             "fromLpd"sv,
                                                             "fromLtep"sv,
                                                             "fromPex"sv,
                                                             "fromTracker"sv,
                                                             "group"sv,
                                                             "hasAnnounced"sv,
                                                             "hasScraped"sv,
                                                             "hashString"sv,
                                                             "have"sv,
                                                             "haveUnchecked"sv,
                                                             "haveValid"sv,
                                                             "honorsSessionLimits"sv,
                                                             "host"sv,
                                                             "id"sv,
                                                             "idle-limit"sv,
                                                             "idle-mode"sv,
                                                             "idle-seeding-limit"sv,
                                                             "idle-seeding-limit-enabled"sv,
                                                             "ids"sv,
                                                             "incomplete"sv,
                                                             "incomplete-dir"sv,
                                                             "incomplete-dir-enabled"sv,
                                                             "info"sv,
                                                             "inhibit-desktop-hibernation"sv,
                                                             "ipv4"sv,
                                                             "ipv6"sv,
                                                             "isBackup"sv,
                                                             "isDownloadingFrom"sv,
                                                             "isEncrypted"sv,
                                                             "isFinished"sv,
                                                             "isIncoming"sv,
                                                             "isPrivate"sv,
                                                             "isStalled"sv,
                                                             "isUTP"sv,
                                                             "isUploadingTo"sv,
                                                             "labels"sv,
                                                             "lastAnnouncePeerCount"sv,
                                                             "lastAnnounceResult"sv,
                                                             "lastAnnounceStartTime"sv,
                                                             "lastAnnounceSucceeded"sv,
                                                             "lastAnnounceTime"sv,
                                                             "lastAnnounceTimedOut"sv,
                                                             "lastScrapeResult"sv,
                                                             "lastScrapeStartTime"sv,
                                                             "lastScrapeSucceeded"sv,
                                                             "lastScrapeTime"sv,
                                                             "lastScrapeTimedOut"sv,
                                                             "leecherCount"sv,
                                                             "leftUntilDone"sv,
                                                             "length"sv,
                                                             "location"sv,
                                                             "lpd-enabled"sv,
                                                             "m"sv,
                                                             "magnetLink"sv,
                                                             "main-window-height"sv,
                                                             "main-window-is-maximized"sv,
                                                             "main-window-layout-order"sv,
                                                             "main-window-width"sv,
                                                             "main-window-x"sv,
                                                             "main-window-y"sv,
                                                             "manualAnnounceTime"sv,
                                                             "max-peers"sv,
                                                             "maxConnectedPeers"sv,
                                                             "memory-bytes"sv,
                                                             "memory-units"sv,
                                                             "message-level"sv,
                                                             "metadataPercentComplete"sv,
                                                             "metadata_size"sv,
                                                             "metainfo"sv,
                                                             "method"sv,
                                                             "min_request_interval"sv,
                                                             "move"sv,
                                                             "msg_type"sv,
                                                             "mtimes"sv,
                                                             "name"sv,
                                                             "name.utf-8"sv,
                                                             "nextAnnounceTime"sv,
                                                             "nextScrapeTime"sv,
                                                             "nodes"sv,
                                                             "nodes6"sv,
                                                             "open-dialog-dir"sv,
                                                             "p"sv,
                                                             "path"sv,
                                                             "path.utf-8"sv,
                                                             "paused"sv,
                                                             "pausedTorrentCount"sv,
                                                             "peer-congestion-algorithm"sv,
                                                             "peer-limit"sv,
                                                             "peer-limit-global"sv,
                                                             "peer-limit-per-torrent"sv,
                                                             "peer-port"sv,
                                                             "peer-port-random-high"sv,
                                                             "peer-port-random-low"sv,
                                                             "peer-port-random-on-start"sv,
                                                             "peer-socket-tos"sv,
                                                             "peerIsChoked"sv,
                                                             "peerIsInterested"sv,
                                                             "peers"sv,
                                                             "peers2"sv,
                                                             "peers2-6"sv,
                                                             "peersConnected"sv,
                                                             "peersFrom"sv,
                                                             "peersGettingFromUs"sv,
                                                             "peersSendingToUs"sv,
                                                             "percentComplete"sv,
                                                             "percentDone"sv,
                                                             "pex-enabled"sv,
                                                             "piece"sv,
                                                             "piece length"sv,
                                                             "pieceCount"sv,
                                                             "pieceSize"sv,
                                                             "pieces"sv,
                                                             "play-download-complete-sound"sv,
                                                             "port"sv,
                                                             "port-forwarding-enabled"sv,
                                                             "port-is-open"sv,
                                                             "preallocation"sv,
                                                             "prefetch-enabled"sv,
                                                             "primary-mime-type"sv,
                                                             "priorities"sv,
                                                             "priority"sv,
                                                             "priority-high"sv,
                                                             "priority-low"sv,
                                                             "priority-normal"sv,
                                                             "private"sv,
                                                             "progress"sv,
                                                             "prompt-before-exit"sv,
                                                             "queue-move-bottom"sv,
                                                             "queue-move-down"sv,
                                                             "queue-move-top"sv,
                                                             "queue-move-up"sv,
                                                             "queue-stalled-enabled"sv,
                                                             "queue-stalled-minutes"sv,
                                                             "queuePosition"sv,
                                                             "rateDownload"sv,
                                                             "rateToClient"sv,
                                                             "rateToPeer"sv,
                                                             "rateUpload"sv,
                                                             "ratio-limit"sv,
                                                             "ratio-limit-enabled"sv,
                                                             "ratio-mode"sv,
                                                             "read-clipboard"sv,
                                                             "recent-download-dir-1"sv,
                                                             "recent-download-dir-2"sv,
                                                             "recent-download-dir-3"sv,
                                                             "recent-download-dir-4"sv,
                                                             "recent-relocate-dir-1"sv,
                                                             "recent-relocate-dir-2"sv,
                                                             "recent-relocate-dir-3"sv,
                                                             "recent-relocate-dir-4"sv,
                                                             "recheckProgress"sv,
                                                             "remote-session-enabled"sv,
                                                             "remote-session-host"sv,
                                                             "remote-session-https"sv,
                                                             "remote-session-password"sv,
                                                             "remote-session-port"sv,
                                                             "remote-session-requres-authentication"sv,
                                                             "remote-session-username"sv,
                                                             "removed"sv,
                                                             "rename-partial-files"sv,
                                                             "reqq"sv,
                                                             "result"sv,
                                                             "rpc-authentication-required"sv,
                                                             "rpc-bind-address"sv,
                                                             "rpc-enabled"sv,
                                                             "rpc-host-whitelist"sv,
                                                             "rpc-host-whitelist-enabled"sv,
                                                             "rpc-password"sv,
                                                             "rpc-port"sv,
                                                             "rpc-socket-mode"sv,
                                                             "rpc-url"sv,
                                                             "rpc-username"sv,
                                                             "rpc-version"sv,
                                                             "rpc-version-minimum"sv,
                                                             "rpc-version-semver"sv,
                                                             "rpc-whitelist"sv,
                                                             "rpc-whitelist-enabled"sv,
                                                             "scrape"sv,
                                                             "scrape-paused-torrents-enabled"sv,
                                                             "scrapeState"sv,
                                                             "script-torrent-added-enabled"sv,
                                                             "script-torrent-added-filename"sv,
                                                             "script-torrent-done-enabled"sv,
                                                             "script-torrent-done-filename"sv,
                                                             "script-torrent-done-seeding-enabled"sv,
                                                             "script-torrent-done-seeding-filename"sv,
                                                             "seconds-active"sv,
                                                             "secondsActive"sv,
                                                             "secondsDownloading"sv,
                                                             "secondsSeeding"sv,
                                                             "seed-queue-enabled"sv,
                                                             "seed-queue-size"sv,
                                                             "seedIdleLimit"sv,
                                                             "seedIdleMode"sv,
                                                             "seedRatioLimit"sv,
                                                             "seedRatioLimited"sv,
                                                             "seedRatioMode"sv,
                                                             "seederCount"sv,
                                                             "seeding-time-seconds"sv,
                                                             "session-count"sv,
                                                             "session-id"sv,
                                                             "sessionCount"sv,
                                                             "show-backup-trackers"sv,
                                                             "show-extra-peer-details"sv,
                                                             "show-filterbar"sv,
                                                             "show-notification-area-icon"sv,
                                                             "show-options-window"sv,
                                                             "show-statusbar"sv,
                                                             "show-toolbar"sv,
                                                             "show-tracker-scrapes"sv,
                                                             "sitename"sv,
                                                             "size-bytes"sv,
                                                             "size-units"sv,
                                                             "sizeWhenDone"sv,
                                                             "sort-mode"sv,
                                                             "sort-reversed"sv,
                                                             "source"sv,
                                                             "speed"sv,
                                                             "speed-Bps"sv,
                                                             "speed-bytes"sv,
                                                             "speed-limit-down"sv,
                                                             "speed-limit-down-enabled"sv,
                                                             "speed-limit-up"sv,
                                                             "speed-limit-up-enabled"sv,
                                                             "speed-units"sv,
                                                             "start-added-torrents"sv,
                                                             "start-minimized"sv,
                                                             "startDate"sv,
                                                             "status"sv,
                                                             "statusbar-stats"sv,
                                                             "tag"sv,
                                                             "tcp-enabled"sv,
                                                             "tier"sv,
                                                             "time-checked"sv,
                                                             "torrent-added"sv,
                                                             "torrent-added-notification-command"sv,
                                                             "torrent-added-notification-enabled"sv,
                                                             "torrent-added-verify-mode"sv,
                                                             "torrent-complete-notification-command"sv,
                                                             "torrent-complete-notification-enabled"sv,
                                                             "torrent-complete-sound-command"sv,
                                                             "torrent-complete-sound-enabled"sv,
                                                             "torrent-duplicate"sv,
                                                             "torrent-get"sv,
                                                             "torrent-set"sv,
                                                             "torrent-set-location"sv,
                                                             "torrentCount"sv,
                                                             "torrentFile"sv,
                                                             "torrents"sv,
                                                             "totalSize"sv,
                                                             "total_size"sv,
                                                             "trackerAdd"sv,
                                                             "trackerList"sv,
                                                             "trackerRemove"sv,
                                                             "trackerReplace"sv,
                                                             "trackerStats"sv,
                                                             "trackers"sv,
                                                             "trash-can-enabled"sv,
                                                             "trash-original-torrent-files"sv,
                                                             "umask"sv,
                                                             "units"sv,
                                                             "upload-slots-per-torrent"sv,
                                                             "uploadLimit"sv,
                                                             "uploadLimited"sv,
                                                             "uploadRatio"sv,
                                                             "uploadSpeed"sv,
                                                             "upload_only"sv,
                                                             "uploaded"sv,
                                                             "uploaded-bytes"sv,
                                                             "uploadedBytes"sv,
                                                             "uploadedEver"sv,
                                                             "url-list"sv,
                                                             "use-global-speed-limit"sv,
                                                             "use-speed-limit"sv,
                                                             "user-has-given-informed-consent"sv,
                                                             "ut_comment"sv,
                                                             "ut_holepunch"sv,
                                                             "ut_metadata"sv,
                                                             "ut_pex"sv,
                                                             "ut_recommend"sv,
                                                             "utp-enabled"sv,
                                                             "v"sv,
                                                             "version"sv,
                                                             "wanted"sv,
                                                             "watch-dir"sv,
                                                             "watch-dir-enabled"sv,
                                                             "webseeds"sv,
                                                             "webseedsSendingToUs"sv,
                                                             "yourip"sv };

bool constexpr quarks_are_sorted()
{
    for (size_t i = 1; i < std::size(MyStatic); ++i)
    {
        if (MyStatic[i - 1] >= MyStatic[i])
        {
            return false;
        }
    }

    return true;
}

static_assert(quarks_are_sorted(), "Predefined quarks must be sorted by their string value");
static_assert(std::size(MyStatic) == TR_N_KEYS);

auto& my_runtime{ *new std::vector<std::string_view>{} };

} // namespace

std::optional<tr_quark> tr_quark_lookup(std::string_view key)
{
    // is it in our static array?
    auto constexpr Sbegin = std::begin(MyStatic);
    auto constexpr Send = std::end(MyStatic);

    if (auto const sit = std::lower_bound(Sbegin, Send, key); sit != Send && *sit == key)
    {
        return std::distance(Sbegin, sit);
    }

    /* was it added during runtime? */
    auto const rbegin = std::begin(my_runtime);
    auto const rend = std::end(my_runtime);
    if (auto const rit = std::find(rbegin, rend, key); rit != rend)
    {
        return TR_N_KEYS + std::distance(rbegin, rit);
    }

    return {};
}

tr_quark tr_quark_new(std::string_view str)
{
    if (auto const prior = tr_quark_lookup(str); prior)
    {
        return *prior;
    }

    auto const ret = TR_N_KEYS + std::size(my_runtime);
    auto const len = std::size(str);
    auto* perma = new char[len + 1];
    std::copy_n(std::begin(str), len, perma);
    perma[len] = '\0';
    my_runtime.emplace_back(perma);
    return ret;
}

std::string_view tr_quark_get_string_view(tr_quark q)
{
    return q < TR_N_KEYS ? MyStatic[q] : my_runtime[q - TR_N_KEYS];
}
