// RLS isolation for the QAF-Differences ownership class (KAR-799).
//
// All 14 qaf_* tables share the same `*_own` predicate
// (`project_id IN (SELECT id FROM projects WHERE user_id = auth.uid())`) plus an
// `*_admin` override. qaf_comparison is the representative — one proof covers
// the class. Confidential BMW/supplier cost data must never leak across owners.
//
// Gated on RLS_TEST_DATABASE_URL → skips in CI, runs via scripts/rls-test/run.sh.

import { describe, it, expect, beforeAll, afterAll } from 'vitest'
import { Client } from 'pg'

const DB_URL = process.env.RLS_TEST_DATABASE_URL
const USER_A = 'aaaa1111-0000-0000-0000-000000000001'
const USER_B = 'bbbb2222-0000-0000-0000-000000000002'
const USER_A_PROJECT = '9999aaaa-0000-0000-0000-0000000000a1'

describe.skipIf(!DB_URL)('RLS isolation — qaf_comparison (KAR-799)', () => {
  let client: Client

  beforeAll(async () => {
    client = new Client({ connectionString: DB_URL })
    await client.connect()
  })

  afterAll(async () => {
    await client?.end()
  })

  async function asUser(uid: string, sql: string, params: unknown[] = []) {
    await client.query('RESET ROLE')
    await client.query('SET ROLE authenticated')
    await client.query("SELECT set_config('request.jwt.claim.sub', $1, false)", [uid])
    return client.query(sql, params)
  }

  it('user_a sees their own qaf_comparison', async () => {
    const r = await asUser(USER_A, 'SELECT count(*)::int AS n FROM public.qaf_comparison')
    expect(r.rows[0].n).toBeGreaterThanOrEqual(1)
  })

  it('user_b sees an empty set (no cross-owner read)', async () => {
    const r = await asUser(USER_B, 'SELECT count(*)::int AS n FROM public.qaf_comparison')
    expect(r.rows[0].n).toBe(0)
  })

  it('user_b UPDATE on user_a qaf_comparison affects 0 rows', async () => {
    const r = await asUser(
      USER_B,
      "UPDATE public.qaf_comparison SET part_number = 'hijacked' WHERE part_number = 'USERA-PART'",
    )
    expect(r.rowCount).toBe(0)
  })

  it('user_b DELETE on user_a qaf_comparison affects 0 rows', async () => {
    const r = await asUser(USER_B, "DELETE FROM public.qaf_comparison WHERE part_number = 'USERA-PART'")
    expect(r.rowCount).toBe(0)
  })

  it('user_b INSERT into user_a project is rejected by RLS', async () => {
    await expect(
      asUser(
        USER_B,
        'INSERT INTO public.qaf_comparison (project_id, part_number) VALUES ($1, $2)',
        [USER_A_PROJECT, 'INJECTED'],
      ),
    ).rejects.toThrow(/row-level security/i)
  })

  it('the qaf_comparison is still intact after user_b write attempts', async () => {
    const r = await asUser(
      USER_A,
      'SELECT part_number FROM public.qaf_comparison WHERE project_id = $1 LIMIT 1',
      [USER_A_PROJECT],
    )
    expect(r.rows[0]?.part_number).toBe('USERA-PART')
  })
})
