CREATE TABLE IF NOT EXISTS fabric_entry_points (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    cluster_id UUID NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
    name TEXT NOT NULL,
    status TEXT NOT NULL DEFAULT 'active',
    endpoint_type TEXT NOT NULL DEFAULT 'client_access',
    public_endpoint TEXT,
    policy JSONB NOT NULL DEFAULT '{}'::JSONB,
    metadata 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 fabric_entry_points_status_check
        CHECK (status IN ('active', 'disabled', 'maintenance')),
    CONSTRAINT fabric_entry_points_type_check
        CHECK (endpoint_type IN ('client_access', 'admin', 'api', 'other'))
);

CREATE UNIQUE INDEX IF NOT EXISTS idx_fabric_entry_points_cluster_name
    ON fabric_entry_points(cluster_id, LOWER(name));

CREATE INDEX IF NOT EXISTS idx_fabric_entry_points_cluster_status
    ON fabric_entry_points(cluster_id, status, endpoint_type);

CREATE TABLE IF NOT EXISTS fabric_entry_point_nodes (
    entry_point_id UUID NOT NULL REFERENCES fabric_entry_points(id) ON DELETE CASCADE,
    cluster_id UUID NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
    node_id UUID NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,
    status TEXT NOT NULL DEFAULT 'active',
    priority INTEGER NOT NULL DEFAULT 100,
    metadata JSONB NOT NULL DEFAULT '{}'::JSONB,
    added_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
    added_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    PRIMARY KEY (entry_point_id, node_id),
    CONSTRAINT fabric_entry_point_nodes_status_check
        CHECK (status IN ('active', 'disabled', 'maintenance')),
    CONSTRAINT fabric_entry_point_nodes_priority_check
        CHECK (priority >= 0)
);

CREATE INDEX IF NOT EXISTS idx_fabric_entry_point_nodes_cluster_node
    ON fabric_entry_point_nodes(cluster_id, node_id, status);

CREATE TABLE IF NOT EXISTS fabric_egress_pools (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    cluster_id UUID NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
    name TEXT NOT NULL,
    status TEXT NOT NULL DEFAULT 'active',
    description TEXT,
    route_scope JSONB NOT NULL DEFAULT '{}'::JSONB,
    policy JSONB NOT NULL DEFAULT '{}'::JSONB,
    metadata 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 fabric_egress_pools_status_check
        CHECK (status IN ('active', 'disabled', 'maintenance'))
);

CREATE UNIQUE INDEX IF NOT EXISTS idx_fabric_egress_pools_cluster_name
    ON fabric_egress_pools(cluster_id, LOWER(name));

CREATE INDEX IF NOT EXISTS idx_fabric_egress_pools_cluster_status
    ON fabric_egress_pools(cluster_id, status);

CREATE TABLE IF NOT EXISTS fabric_egress_pool_nodes (
    egress_pool_id UUID NOT NULL REFERENCES fabric_egress_pools(id) ON DELETE CASCADE,
    cluster_id UUID NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
    node_id UUID NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,
    status TEXT NOT NULL DEFAULT 'active',
    priority INTEGER NOT NULL DEFAULT 100,
    metadata JSONB NOT NULL DEFAULT '{}'::JSONB,
    added_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
    added_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    PRIMARY KEY (egress_pool_id, node_id),
    CONSTRAINT fabric_egress_pool_nodes_status_check
        CHECK (status IN ('active', 'disabled', 'maintenance')),
    CONSTRAINT fabric_egress_pool_nodes_priority_check
        CHECK (priority >= 0)
);

CREATE INDEX IF NOT EXISTS idx_fabric_egress_pool_nodes_cluster_node
    ON fabric_egress_pool_nodes(cluster_id, node_id, status);
