"""SQLite schema definition for the Unfamiliar database.

This module contains the complete DDL for all MVP tables and indexes.
Schema version is tracked in the meta table for upgrade detection.

v1.0 fields marked as v1.1 (mode, character) are included with defaults
to avoid ALTER TABLE operations in future versions.
"""

SCHEMA_VERSION = "1.0"

SCHEMA_SQL = """
-- Meta table for schema version and other metadata
CREATE TABLE IF NOT EXISTS meta (
    key TEXT PRIMARY KEY,
    value TEXT NOT NULL
);

-- Campaign: An investigation of a codebase
CREATE TABLE IF NOT EXISTS campaign (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    repo_path TEXT NOT NULL UNIQUE,
    schema_version TEXT NOT NULL DEFAULT '1.0',
    mode TEXT NOT NULL DEFAULT 'onboarding',
    character TEXT NOT NULL DEFAULT 'detective',
    status TEXT NOT NULL DEFAULT 'initializing',
    theme TEXT NOT NULL DEFAULT 'film_noir',
    created_at TEXT,
    updated_at TEXT
);

-- Briefing: LLM-generated codebase summary (one-to-one with Campaign)
CREATE TABLE IF NOT EXISTS briefing (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    campaign_id INTEGER NOT NULL UNIQUE,
    summary TEXT NOT NULL,
    tech_stack TEXT NOT NULL DEFAULT '[]',
    security_posture TEXT NOT NULL,
    created_at TEXT,
    updated_at TEXT,
    FOREIGN KEY (campaign_id) REFERENCES campaign(id) ON DELETE CASCADE
);

-- Module: A logical code unit discovered during analysis
CREATE TABLE IF NOT EXISTS module (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    campaign_id INTEGER NOT NULL,
    name TEXT NOT NULL,
    path TEXT NOT NULL,
    description TEXT NOT NULL,
    file_count INTEGER NOT NULL DEFAULT 0,
    category_relevance TEXT NOT NULL DEFAULT '[]',
    security_relevant INTEGER NOT NULL DEFAULT 0,
    created_at TEXT,
    updated_at TEXT,
    FOREIGN KEY (campaign_id) REFERENCES campaign(id) ON DELETE CASCADE
);

-- Mission: An atomic investigation task
CREATE TABLE IF NOT EXISTS mission (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    campaign_id INTEGER NOT NULL,
    title TEXT NOT NULL,
    title_plain TEXT NOT NULL,
    description TEXT NOT NULL,
    category TEXT NOT NULL,
    difficulty TEXT NOT NULL,
    time_estimate_minutes INTEGER NOT NULL,
    completion_condition TEXT NOT NULL,
    security_tag INTEGER NOT NULL DEFAULT 0,
    standard_tag TEXT,
    status TEXT NOT NULL DEFAULT 'locked',
    completion_method TEXT,
    narrative_intro TEXT NOT NULL DEFAULT '',
    narrative_outro TEXT NOT NULL DEFAULT '',
    created_at TEXT,
    updated_at TEXT,
    FOREIGN KEY (campaign_id) REFERENCES campaign(id) ON DELETE CASCADE
);

-- MissionFileRef: Links missions to specific files/lines
CREATE TABLE IF NOT EXISTS mission_file_ref (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    mission_id INTEGER NOT NULL,
    file_path TEXT NOT NULL,
    line_start INTEGER,
    line_end INTEGER,
    description TEXT NOT NULL DEFAULT '',
    file_hash TEXT NOT NULL DEFAULT '',
    FOREIGN KEY (mission_id) REFERENCES mission(id) ON DELETE CASCADE
);

-- MissionPrerequisite: DAG of mission dependencies
CREATE TABLE IF NOT EXISTS mission_prerequisite (
    prerequisite_id INTEGER NOT NULL,
    dependent_id INTEGER NOT NULL,
    PRIMARY KEY (prerequisite_id, dependent_id),
    FOREIGN KEY (prerequisite_id) REFERENCES mission(id) ON DELETE CASCADE,
    FOREIGN KEY (dependent_id) REFERENCES mission(id) ON DELETE CASCADE
);

-- ModuleMission: Many-to-many link between modules and missions
CREATE TABLE IF NOT EXISTS module_mission (
    module_id INTEGER NOT NULL,
    mission_id INTEGER NOT NULL,
    is_primary INTEGER NOT NULL DEFAULT 0,
    PRIMARY KEY (module_id, mission_id),
    FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE,
    FOREIGN KEY (mission_id) REFERENCES mission(id) ON DELETE CASCADE
);

-- MissionChain: A suggested learning path through related missions
CREATE TABLE IF NOT EXISTS mission_chain (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    campaign_id INTEGER NOT NULL,
    name TEXT NOT NULL,
    name_plain TEXT NOT NULL,
    description TEXT NOT NULL,
    category TEXT NOT NULL,
    sort_order INTEGER NOT NULL DEFAULT 0,
    created_at TEXT,
    updated_at TEXT,
    FOREIGN KEY (campaign_id) REFERENCES campaign(id) ON DELETE CASCADE
);

-- ChainMission: Links chains to their constituent missions in order
CREATE TABLE IF NOT EXISTS chain_mission (
    chain_id INTEGER NOT NULL,
    mission_id INTEGER NOT NULL,
    position INTEGER NOT NULL,
    PRIMARY KEY (chain_id, mission_id),
    FOREIGN KEY (chain_id) REFERENCES mission_chain(id) ON DELETE CASCADE,
    FOREIGN KEY (mission_id) REFERENCES mission(id) ON DELETE CASCADE
);

-- FileSnapshot: Tracks file state at analysis time
CREATE TABLE IF NOT EXISTS file_snapshot (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    campaign_id INTEGER NOT NULL,
    file_path TEXT NOT NULL,
    file_hash TEXT NOT NULL,
    last_analyzed TEXT,
    FOREIGN KEY (campaign_id) REFERENCES campaign(id) ON DELETE CASCADE
);

-- Indexes for common query patterns

-- Campaign lookups
CREATE INDEX IF NOT EXISTS idx_campaign_status ON campaign(status);
CREATE INDEX IF NOT EXISTS idx_campaign_repo_path ON campaign(repo_path);

-- Briefing lookups
CREATE INDEX IF NOT EXISTS idx_briefing_campaign ON briefing(campaign_id);

-- Module lookups
CREATE INDEX IF NOT EXISTS idx_module_campaign ON module(campaign_id);
CREATE INDEX IF NOT EXISTS idx_module_path ON module(campaign_id, path);

-- Mission lookups
CREATE INDEX IF NOT EXISTS idx_mission_campaign ON mission(campaign_id);
CREATE INDEX IF NOT EXISTS idx_mission_status ON mission(campaign_id, status);
CREATE INDEX IF NOT EXISTS idx_mission_category ON mission(campaign_id, category);

-- Mission file ref lookups
CREATE INDEX IF NOT EXISTS idx_mission_file_ref_mission ON mission_file_ref(mission_id);

-- Mission prerequisite lookups (both directions)
CREATE INDEX IF NOT EXISTS idx_prereq_dependent
    ON mission_prerequisite(dependent_id);
CREATE INDEX IF NOT EXISTS idx_prereq_prereq
    ON mission_prerequisite(prerequisite_id);

-- Module-mission link lookups
CREATE INDEX IF NOT EXISTS idx_module_mission_module ON module_mission(module_id);
CREATE INDEX IF NOT EXISTS idx_module_mission_mission ON module_mission(mission_id);

-- Chain lookups
CREATE INDEX IF NOT EXISTS idx_chain_campaign ON mission_chain(campaign_id);
CREATE INDEX IF NOT EXISTS idx_chain_mission_chain ON chain_mission(chain_id);
CREATE INDEX IF NOT EXISTS idx_chain_mission_mission ON chain_mission(mission_id);

-- File snapshot lookups
CREATE INDEX IF NOT EXISTS idx_snapshot_campaign ON file_snapshot(campaign_id);
CREATE UNIQUE INDEX IF NOT EXISTS idx_snapshot_path
    ON file_snapshot(campaign_id, file_path);
"""
