CREATE TABLE IF NOT EXISTS source (
    id INTEGER PRIMARY KEY,
    created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    name TEXT NOT NULL,
    slug TEXT NOT NULL UNIQUE,
    source_type TEXT NOT NULL CHECK (source_type IN ('feed', 'pangea')),
    notes TEXT NOT NULL DEFAULT ''
);

CREATE TABLE IF NOT EXISTS source_feed (
    source_id INTEGER PRIMARY KEY,
    feed_url TEXT NOT NULL,
    etag TEXT,
    last_modified TEXT,
    FOREIGN KEY (source_id) REFERENCES source(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS source_pangea (
    source_id INTEGER PRIMARY KEY,
    domain TEXT NOT NULL,
    category_name TEXT NOT NULL,
    content_type TEXT NOT NULL,
    only_newest INTEGER NOT NULL CHECK (only_newest IN (0, 1)),
    max_articles INTEGER NOT NULL,
    oldest_article INTEGER NOT NULL,
    include_authors INTEGER NOT NULL CHECK (include_authors IN (0, 1)),
    exclude_media INTEGER NOT NULL CHECK (exclude_media IN (0, 1)),
    include_content INTEGER NOT NULL CHECK (include_content IN (0, 1)),
    content_format TEXT NOT NULL,
    FOREIGN KEY (source_id) REFERENCES source(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS job (
    id INTEGER PRIMARY KEY,
    source_id INTEGER NOT NULL UNIQUE,
    created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    enabled INTEGER NOT NULL CHECK (enabled IN (0, 1)),
    spider_arguments TEXT NOT NULL DEFAULT '',
    cron_minute TEXT NOT NULL,
    cron_hour TEXT NOT NULL,
    cron_day_of_month TEXT NOT NULL,
    cron_day_of_week TEXT NOT NULL,
    cron_month TEXT NOT NULL,
    FOREIGN KEY (source_id) REFERENCES source(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS job_execution (
    id INTEGER PRIMARY KEY,
    job_id INTEGER NOT NULL,
    created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    started_at TEXT,
    ended_at TEXT,
    stop_requested_at TEXT,
    running_status INTEGER NOT NULL DEFAULT 0 CHECK (running_status BETWEEN 0 AND 4),
    requests_count INTEGER NOT NULL DEFAULT 0,
    items_count INTEGER NOT NULL DEFAULT 0,
    warnings_count INTEGER NOT NULL DEFAULT 0,
    errors_count INTEGER NOT NULL DEFAULT 0,
    bytes_count INTEGER NOT NULL DEFAULT 0,
    retries_count INTEGER NOT NULL DEFAULT 0,
    exceptions_count INTEGER NOT NULL DEFAULT 0,
    cache_size_count INTEGER NOT NULL DEFAULT 0,
    cache_object_count INTEGER NOT NULL DEFAULT 0,
    raw_stats TEXT NOT NULL DEFAULT '{}',
    FOREIGN KEY (job_id) REFERENCES job(id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS job_enabled_idx
ON job (enabled);

CREATE INDEX IF NOT EXISTS job_execution_job_created_at_idx
ON job_execution (job_id, created_at DESC);

CREATE INDEX IF NOT EXISTS job_execution_status_started_at_idx
ON job_execution (running_status, started_at DESC);

CREATE INDEX IF NOT EXISTS job_execution_status_ended_at_idx
ON job_execution (running_status, ended_at DESC);

CREATE TRIGGER IF NOT EXISTS source_set_updated_at
AFTER UPDATE ON source
FOR EACH ROW
BEGIN
    UPDATE source
    SET updated_at = CURRENT_TIMESTAMP
    WHERE id = NEW.id;
END;

CREATE TRIGGER IF NOT EXISTS job_set_updated_at
AFTER UPDATE ON job
FOR EACH ROW
BEGIN
    UPDATE job
    SET updated_at = CURRENT_TIMESTAMP
    WHERE id = NEW.id;
END;
