-- AtlasOS - Calypso
-- Storage and Tape Component Schema
-- Version: 2.0

-- ZFS pools table
CREATE TABLE IF NOT EXISTS zfs_pools (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL UNIQUE,
    description TEXT,
    raid_level VARCHAR(50) NOT NULL, -- stripe, mirror, raidz, raidz2, raidz3
    disks TEXT[] NOT NULL, -- array of device paths
    size_bytes BIGINT NOT NULL,
    used_bytes BIGINT NOT NULL DEFAULT 0,
    compression VARCHAR(50) NOT NULL DEFAULT 'lz4', -- off, lz4, zstd, gzip
    deduplication BOOLEAN NOT NULL DEFAULT false,
    auto_expand BOOLEAN NOT NULL DEFAULT false,
    scrub_interval INTEGER NOT NULL DEFAULT 30, -- days
    is_active BOOLEAN NOT NULL DEFAULT true,
    health_status VARCHAR(50) NOT NULL DEFAULT 'online', -- online, degraded, faulted, offline
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES users(id)
);

-- Disk repositories table
CREATE TABLE IF NOT EXISTS disk_repositories (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL UNIQUE,
    description TEXT,
    volume_group VARCHAR(255) NOT NULL,
    logical_volume VARCHAR(255) NOT NULL,
    size_bytes BIGINT NOT NULL,
    used_bytes BIGINT NOT NULL DEFAULT 0,
    filesystem_type VARCHAR(50),
    mount_point TEXT,
    is_active BOOLEAN NOT NULL DEFAULT true,
    warning_threshold_percent INTEGER NOT NULL DEFAULT 80,
    critical_threshold_percent INTEGER NOT NULL DEFAULT 90,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES users(id)
);

-- Physical disks table
CREATE TABLE IF NOT EXISTS physical_disks (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    device_path VARCHAR(255) NOT NULL UNIQUE,
    vendor VARCHAR(255),
    model VARCHAR(255),
    serial_number VARCHAR(255),
    size_bytes BIGINT NOT NULL,
    sector_size INTEGER,
    is_ssd BOOLEAN NOT NULL DEFAULT false,
    health_status VARCHAR(50) NOT NULL DEFAULT 'unknown',
    health_details JSONB,
    is_used BOOLEAN NOT NULL DEFAULT false,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- Volume groups table
CREATE TABLE IF NOT EXISTS volume_groups (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL UNIQUE,
    size_bytes BIGINT NOT NULL,
    free_bytes BIGINT NOT NULL,
    physical_volumes TEXT[],
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- SCST iSCSI targets table
CREATE TABLE IF NOT EXISTS scst_targets (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    iqn VARCHAR(512) NOT NULL UNIQUE,
    target_type VARCHAR(50) NOT NULL, -- 'disk', 'vtl', 'physical_tape'
    name VARCHAR(255) NOT NULL,
    description TEXT,
    is_active BOOLEAN NOT NULL DEFAULT true,
    single_initiator_only BOOLEAN NOT NULL DEFAULT false,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES users(id)
);

-- SCST LUN mappings table
CREATE TABLE IF NOT EXISTS scst_luns (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    target_id UUID NOT NULL REFERENCES scst_targets(id) ON DELETE CASCADE,
    lun_number INTEGER NOT NULL,
    device_name VARCHAR(255) NOT NULL,
    device_path VARCHAR(512) NOT NULL,
    handler_type VARCHAR(50) NOT NULL, -- 'vdisk', 'sg', 'tape'
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    UNIQUE(target_id, lun_number)
);

-- SCST initiator groups table
CREATE TABLE IF NOT EXISTS scst_initiator_groups (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    target_id UUID NOT NULL REFERENCES scst_targets(id) ON DELETE CASCADE,
    group_name VARCHAR(255) NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    UNIQUE(target_id, group_name)
);

-- SCST initiators table
CREATE TABLE IF NOT EXISTS scst_initiators (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    group_id UUID NOT NULL REFERENCES scst_initiator_groups(id) ON DELETE CASCADE,
    iqn VARCHAR(512) NOT NULL,
    is_active BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    UNIQUE(group_id, iqn)
);

-- Physical tape libraries table
CREATE TABLE IF NOT EXISTS physical_tape_libraries (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL UNIQUE,
    serial_number VARCHAR(255),
    vendor VARCHAR(255),
    model VARCHAR(255),
    changer_device_path VARCHAR(512),
    changer_stable_path VARCHAR(512),
    slot_count INTEGER,
    drive_count INTEGER,
    is_active BOOLEAN NOT NULL DEFAULT true,
    discovered_at TIMESTAMP NOT NULL DEFAULT NOW(),
    last_inventory_at TIMESTAMP,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- Physical tape drives table
CREATE TABLE IF NOT EXISTS physical_tape_drives (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    library_id UUID NOT NULL REFERENCES physical_tape_libraries(id) ON DELETE CASCADE,
    drive_number INTEGER NOT NULL,
    device_path VARCHAR(512),
    stable_path VARCHAR(512),
    vendor VARCHAR(255),
    model VARCHAR(255),
    serial_number VARCHAR(255),
    drive_type VARCHAR(50), -- 'LTO-8', 'LTO-9', etc.
    status VARCHAR(50) NOT NULL DEFAULT 'unknown', -- 'idle', 'loading', 'ready', 'error'
    current_tape_barcode VARCHAR(255),
    is_active BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
    UNIQUE(library_id, drive_number)
);

-- Physical tape slots table
CREATE TABLE IF NOT EXISTS physical_tape_slots (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    library_id UUID NOT NULL REFERENCES physical_tape_libraries(id) ON DELETE CASCADE,
    slot_number INTEGER NOT NULL,
    barcode VARCHAR(255),
    tape_present BOOLEAN NOT NULL DEFAULT false,
    tape_type VARCHAR(50),
    last_updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
    UNIQUE(library_id, slot_number)
);

-- Virtual tape libraries table
CREATE TABLE IF NOT EXISTS virtual_tape_libraries (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL UNIQUE,
    description TEXT,
    mhvtl_library_id INTEGER,
    backing_store_path TEXT NOT NULL,
    slot_count INTEGER NOT NULL DEFAULT 10,
    drive_count INTEGER NOT NULL DEFAULT 2,
    is_active BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES users(id)
);

-- Virtual tape drives table
CREATE TABLE IF NOT EXISTS virtual_tape_drives (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    library_id UUID NOT NULL REFERENCES virtual_tape_libraries(id) ON DELETE CASCADE,
    drive_number INTEGER NOT NULL,
    device_path VARCHAR(512),
    stable_path VARCHAR(512),
    status VARCHAR(50) NOT NULL DEFAULT 'idle',
    current_tape_id UUID,
    is_active BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
    UNIQUE(library_id, drive_number)
);

-- Virtual tapes table
CREATE TABLE IF NOT EXISTS virtual_tapes (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    library_id UUID NOT NULL REFERENCES virtual_tape_libraries(id) ON DELETE CASCADE,
    barcode VARCHAR(255) NOT NULL,
    slot_number INTEGER,
    image_file_path TEXT NOT NULL,
    size_bytes BIGINT NOT NULL DEFAULT 0,
    used_bytes BIGINT NOT NULL DEFAULT 0,
    tape_type VARCHAR(50) NOT NULL DEFAULT 'LTO-8',
    status VARCHAR(50) NOT NULL DEFAULT 'idle', -- 'idle', 'in_drive', 'exported'
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
    UNIQUE(library_id, barcode)
);

-- Indexes for performance
CREATE INDEX IF NOT EXISTS idx_disk_repositories_name ON disk_repositories(name);
CREATE INDEX IF NOT EXISTS idx_disk_repositories_active ON disk_repositories(is_active);
CREATE INDEX IF NOT EXISTS idx_physical_disks_device_path ON physical_disks(device_path);
CREATE INDEX IF NOT EXISTS idx_scst_targets_iqn ON scst_targets(iqn);
CREATE INDEX IF NOT EXISTS idx_scst_targets_type ON scst_targets(target_type);
CREATE INDEX IF NOT EXISTS idx_scst_luns_target_id ON scst_luns(target_id);
CREATE INDEX IF NOT EXISTS idx_scst_initiators_group_id ON scst_initiators(group_id);
CREATE INDEX IF NOT EXISTS idx_physical_tape_libraries_name ON physical_tape_libraries(name);
CREATE INDEX IF NOT EXISTS idx_physical_tape_drives_library_id ON physical_tape_drives(library_id);
CREATE INDEX IF NOT EXISTS idx_physical_tape_slots_library_id ON physical_tape_slots(library_id);
CREATE INDEX IF NOT EXISTS idx_virtual_tape_libraries_name ON virtual_tape_libraries(name);
CREATE INDEX IF NOT EXISTS idx_virtual_tape_drives_library_id ON virtual_tape_drives(library_id);
CREATE INDEX IF NOT EXISTS idx_virtual_tapes_library_id ON virtual_tapes(library_id);
CREATE INDEX IF NOT EXISTS idx_virtual_tapes_barcode ON virtual_tapes(barcode);

