/**
 * @vitest-environment node
 */
import { describe, expect, it } from 'vitest'
import {
  getCookieHeaderValue,
  rewriteCookieHeaderForUpstream,
  rewriteSetCookieHeadersForLocal,
  toScopedLocalCookieName,
} from './cookies'

describe('dev proxy cookies', () => {
  // Scenario: cookie names should only receive secure host prefixes when configured.
  it('should rewrite configured cookie names for HTTPS upstream requests', () => {
    // Act
    const cookieHeader = rewriteCookieHeaderForUpstream(
      'access_token=abc; theme=dark; passport-app=def',
      {
        hostPrefixCookies: ['access_token', /^passport-/],
        useHostPrefix: true,
      },
    )

    // Assert
    expect(cookieHeader).toBe('__Host-access_token=abc; theme=dark; __Host-passport-app=def')
  })

  // Scenario: HTTP upstreams should keep local cookie names even when rewrite config exists.
  it('should keep local cookie names for HTTP upstream requests', () => {
    // Act
    const cookieHeader = rewriteCookieHeaderForUpstream('access_token=abc; refresh_token=def', {
      hostPrefixCookies: ['access_token', 'refresh_token'],
      useHostPrefix: false,
    })

    // Assert
    expect(cookieHeader).toBe('access_token=abc; refresh_token=def')
  })

  // Scenario: upstream set-cookie headers should be converted into localhost-safe cookies.
  it('should rewrite upstream set-cookie headers for local development', () => {
    // Act
    const cookies = rewriteSetCookieHeadersForLocal([
      '__Host-access_token=abc; Path=/console/api; Domain=cloud.example.com; Secure; SameSite=None; Partitioned',
    ])

    // Assert
    expect(cookies).toEqual(['access_token=abc; Path=/; SameSite=Lax'])
  })

  // Scenario: target-scoped cookies should isolate authentication state between upstream targets.
  it('should only forward auth cookies from the active local scope', () => {
    // Arrange
    const activeAccessTokenName = toScopedLocalCookieName('access_token', 'active')
    const otherAccessTokenName = toScopedLocalCookieName('access_token', 'other')

    // Act
    const cookieHeader = rewriteCookieHeaderForUpstream(
      [
        `${activeAccessTokenName}=active-token`,
        'access_token=legacy-token',
        `${otherAccessTokenName}=other-token`,
        'theme=dark',
      ].join('; '),
      {
        hostPrefixCookies: ['access_token'],
        localScopeKey: 'active',
        useHostPrefix: true,
      },
    )

    // Assert
    expect(cookieHeader).toBe('__Host-access_token=active-token; theme=dark')
  })

  // Scenario: upstream auth set-cookie headers should be stored under scoped local names.
  it('should rewrite upstream set-cookie headers into target-scoped local cookies', () => {
    // Arrange
    const scopedAccessTokenName = toScopedLocalCookieName('access_token', 'cloud')

    // Act
    const cookies = rewriteSetCookieHeadersForLocal(
      [
        '__Host-access_token=abc; Path=/console/api; Domain=cloud.example.com; Secure; SameSite=None; Partitioned',
      ],
      {
        hostPrefixCookies: ['access_token'],
        localScopeKey: 'cloud',
      },
    )

    // Assert
    expect(cookies).toEqual([`${scopedAccessTokenName}=abc; Path=/; SameSite=Lax`])
  })

  // Scenario: request header helpers should read scoped CSRF cookies without exposing scope logic to callers.
  it('should read scoped cookie values from cookie headers', () => {
    // Arrange
    const scopedCsrfCookieName = toScopedLocalCookieName('csrf_token', 'cloud')

    // Act
    const csrfToken = getCookieHeaderValue(
      `${scopedCsrfCookieName}=csrf; csrf_token=legacy`,
      scopedCsrfCookieName,
    )

    // Assert
    expect(csrfToken).toBe('csrf')
  })
})
