/**
 * requireProductAccess — flag-gated, owner-scoped tenant authorization (§tenancy).
 */

import { describe, it, expect, vi, afterEach } from 'vitest';
import type { FastifyRequest } from 'fastify';

let authPayload: { sub: string; role?: string } = { sub: 'owner_1', role: 'user' };

vi.mock('./auth.js', () => ({ extractAuth: vi.fn(async () => authPayload) }));
vi.mock('./auto-register.js', () => ({ autoRegisterProduct: vi.fn() }));
vi.mock('../modules/products/cache.js', () => ({
  isValidProduct: () => true,
  getProduct: (id: string) => ({ id, productId: id, status: 'active', ownerId: 'owner_1' }),
}));

import { requireProductAccess, isTenantEnforcementEnabled } from './request-context.js';
import { ForbiddenError } from './errors.js';

const reqFor = (productId: string): FastifyRequest =>
  ({ jwtPayload: { sub: authPayload.sub, productId }, headers: {} }) as unknown as FastifyRequest;

afterEach(() => {
  delete process.env.FLEET_TENANT_ENFORCEMENT;
  authPayload = { sub: 'owner_1', role: 'user' };
});

describe('requireProductAccess', () => {
  it('enforcement OFF (default): resolves without an access check', async () => {
    authPayload = { sub: 'someone_else', role: 'user' };
    await expect(requireProductAccess(reqFor('p1'))).resolves.toBe('p1');
    expect(isTenantEnforcementEnabled()).toBe(false);
  });

  it('enforcement ON: the owner is allowed', async () => {
    process.env.FLEET_TENANT_ENFORCEMENT = '1';
    authPayload = { sub: 'owner_1', role: 'user' };
    await expect(requireProductAccess(reqFor('p1'))).resolves.toBe('p1');
  });

  it('enforcement ON: a non-owner, non-admin user is rejected (403)', async () => {
    process.env.FLEET_TENANT_ENFORCEMENT = '1';
    authPayload = { sub: 'intruder', role: 'user' };
    await expect(requireProductAccess(reqFor('p1'))).rejects.toBeInstanceOf(ForbiddenError);
  });

  it('enforcement ON: admins and super_admins are always allowed', async () => {
    process.env.FLEET_TENANT_ENFORCEMENT = '1';
    authPayload = { sub: 'intruder', role: 'admin' };
    await expect(requireProductAccess(reqFor('p1'))).resolves.toBe('p1');
    authPayload = { sub: 'intruder', role: 'super_admin' };
    await expect(requireProductAccess(reqFor('p1'))).resolves.toBe('p1');
  });
});
