-- Cached parsed-torrent metadata. Mirrors the Rust `ParsedTorrent` struct
-- field-for-field. A UUID `id` is the PK so rows can be inserted during the
-- fast path (title-only, no info_hash yet) and updated when the background
-- resolver finishes.
--
-- A row exists in one of three states:
--   'partial'  - title-derived fields only, awaiting background resolution
--   'resolving'- a background resolver task is currently fetching torrent bytes
--   'resolved' - full torrent-derived data filled in
CREATE TABLE parsed_torrents (
    id                  UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    info_hash           TEXT NOT NULL DEFAULT '',

    raw_title           TEXT NOT NULL DEFAULT '',

    artist              TEXT NOT NULL DEFAULT '',
    album               TEXT NOT NULL DEFAULT '',
    year                INTEGER NOT NULL DEFAULT 0,

    release_type        TEXT NOT NULL DEFAULT 'unknown',
    genres              JSONB NOT NULL DEFAULT '[]'::jsonb,
    label               TEXT NOT NULL DEFAULT '',
    source              TEXT NOT NULL DEFAULT 'unknown',
    rip_type            TEXT NOT NULL DEFAULT '',

    format              TEXT NOT NULL DEFAULT 'unknown',
    bitrate             TEXT NOT NULL DEFAULT '',
    bit_depth           INTEGER NOT NULL DEFAULT 0,
    sample_rate         INTEGER NOT NULL DEFAULT 0,

    track_names         JSONB NOT NULL DEFAULT '[]'::jsonb,
    track_count         INTEGER NOT NULL DEFAULT 0,
    release_count       INTEGER NOT NULL DEFAULT 0,
    audio_file_count    INTEGER NOT NULL DEFAULT 0,
    total_audio_size    BIGINT NOT NULL DEFAULT 0,

    has_cover_art       BOOLEAN NOT NULL DEFAULT false,
    has_cue_sheet       BOOLEAN NOT NULL DEFAULT false,
    has_rip_log         BOOLEAN NOT NULL DEFAULT false,

    parsed_successfully BOOLEAN NOT NULL DEFAULT false,
    parse_errors        JSONB NOT NULL DEFAULT '[]'::jsonb,

    -- cache-control columns (not part of ParsedTorrent)
    state               TEXT NOT NULL DEFAULT 'partial',
    indexer             TEXT NOT NULL DEFAULT '',
    magnet              TEXT NOT NULL DEFAULT '',
    created_at          TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at          TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- enum-backed fields (release_type, source, format) are stored as their
-- `as_str()` repr in plain TEXT rather than native ENUMs, so adding a variant
-- to the Rust enum needs no migration.

-- lets the background resolver find rows still awaiting torrent resolution
CREATE INDEX parsed_torrents_state_idx
    ON parsed_torrents (state)
    WHERE state IN ('partial', 'resolving');

-- dedup resolved torrents by info_hash (only meaningful once non-empty)
CREATE UNIQUE INDEX parsed_torrents_info_hash_uidx
    ON parsed_torrents (info_hash)
    WHERE info_hash != '';

-- Albums that music-agregator has pointed tora at. One row per
-- (album_id, quality) pair: a re-monitor of the same album at the same
-- quality is rejected by the UNIQUE constraint until the previous row is
-- removed. The `torrent_id` column links back to tora's torrent; it's what
-- the startup notification subscriber uses to look up which album a
-- STATE_CHANGED -> FINISHED event belongs to.
CREATE TABLE monitored_albums (
    id            UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    album_id      TEXT NOT NULL,
    torrent_id    UUID NOT NULL,
    quality       TEXT NOT NULL,
    created_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
    completed_at  TIMESTAMPTZ,
    UNIQUE (album_id, quality)
);

CREATE UNIQUE INDEX monitored_albums_torrent_id_uidx
    ON monitored_albums (torrent_id);
