CREATE TABLE IF NOT EXISTS mesh_link_observations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    cluster_id UUID NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
    source_node_id UUID NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,
    target_node_id UUID NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,
    link_status TEXT NOT NULL DEFAULT 'unknown',
    latency_ms INTEGER,
    quality_score INTEGER,
    metadata JSONB NOT NULL DEFAULT '{}'::JSONB,
    observed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    CONSTRAINT mesh_link_observations_status_check
        CHECK (link_status IN ('unknown', 'reachable', 'degraded', 'unreachable')),
    CONSTRAINT mesh_link_observations_quality_check
        CHECK (quality_score IS NULL OR (quality_score >= 0 AND quality_score <= 100))
);

CREATE INDEX IF NOT EXISTS idx_mesh_link_observations_cluster_observed
    ON mesh_link_observations(cluster_id, observed_at DESC);

CREATE TABLE IF NOT EXISTS mesh_latest_links (
    cluster_id UUID NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
    source_node_id UUID NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,
    target_node_id UUID NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,
    observation_id UUID REFERENCES mesh_link_observations(id) ON DELETE SET NULL,
    link_status TEXT NOT NULL DEFAULT 'unknown',
    latency_ms INTEGER,
    quality_score INTEGER,
    metadata JSONB NOT NULL DEFAULT '{}'::JSONB,
    observed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    PRIMARY KEY (cluster_id, source_node_id, target_node_id),
    CONSTRAINT mesh_latest_links_status_check
        CHECK (link_status IN ('unknown', 'reachable', 'degraded', 'unreachable')),
    CONSTRAINT mesh_latest_links_quality_check
        CHECK (quality_score IS NULL OR (quality_score >= 0 AND quality_score <= 100))
);

CREATE TABLE IF NOT EXISTS mesh_route_intents (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    cluster_id UUID NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
    source_selector JSONB NOT NULL DEFAULT '{}'::JSONB,
    destination_selector JSONB NOT NULL DEFAULT '{}'::JSONB,
    service_class TEXT NOT NULL,
    priority INTEGER NOT NULL DEFAULT 100,
    status TEXT NOT NULL DEFAULT 'active',
    policy JSONB NOT NULL DEFAULT '{}'::JSONB,
    created_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    CONSTRAINT mesh_route_intents_service_class_check
        CHECK (service_class IN ('input', 'control', 'render', 'clipboard', 'file_transfer', 'vpn_packets', 'telemetry')),
    CONSTRAINT mesh_route_intents_status_check
        CHECK (status IN ('active', 'disabled'))
);

CREATE INDEX IF NOT EXISTS idx_mesh_route_intents_cluster_class
    ON mesh_route_intents(cluster_id, service_class, status);

CREATE TABLE IF NOT EXISTS mesh_qos_policies (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    cluster_id UUID NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
    service_class TEXT NOT NULL,
    priority INTEGER NOT NULL,
    reliability_mode TEXT NOT NULL,
    drop_policy TEXT NOT NULL,
    bandwidth_policy JSONB NOT NULL DEFAULT '{}'::JSONB,
    metadata JSONB NOT NULL DEFAULT '{}'::JSONB,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    UNIQUE (cluster_id, service_class),
    CONSTRAINT mesh_qos_policies_service_class_check
        CHECK (service_class IN ('input', 'control', 'render', 'clipboard', 'file_transfer', 'vpn_packets', 'telemetry')),
    CONSTRAINT mesh_qos_policies_reliability_check
        CHECK (reliability_mode IN ('reliable', 'droppable', 'adaptive')),
    CONSTRAINT mesh_qos_policies_drop_policy_check
        CHECK (drop_policy IN ('never', 'latest_only', 'adaptive'))
);

INSERT INTO mesh_qos_policies (
    cluster_id, service_class, priority, reliability_mode, drop_policy, bandwidth_policy, metadata
)
SELECT c.id, defaults.service_class, defaults.priority, defaults.reliability_mode,
       defaults.drop_policy, '{}'::jsonb, '{"default":true}'::jsonb
FROM clusters c
CROSS JOIN (
    VALUES
        ('input', 10, 'reliable', 'never'),
        ('control', 20, 'reliable', 'never'),
        ('clipboard', 40, 'reliable', 'never'),
        ('render', 60, 'droppable', 'latest_only'),
        ('file_transfer', 80, 'reliable', 'never'),
        ('telemetry', 120, 'adaptive', 'adaptive'),
        ('vpn_packets', 160, 'adaptive', 'adaptive')
) AS defaults(service_class, priority, reliability_mode, drop_policy)
ON CONFLICT (cluster_id, service_class) DO NOTHING;
