'use strict';

const configureMiddleware = require('../src/utilities/middleware');

function buildSession() {
  const app = {
    param: jest.fn(),
    set: jest.fn(),
    use: jest.fn(),
  };

  return configureMiddleware(app, {
    siteConfig: { dashboardHost: 'status.sami', tld: '.sami' },
    totpConfig: { enabled: true, sessionDuration: '24h' },
    tailscaleConfig: { enabled: false, requireAuth: false },
    metrics: { recordRequest: jest.fn() },
    auditLogger: { middleware: () => (_req, _res, next) => next() },
    authManager: { verifyJWT: jest.fn(), verifyAPIKey: jest.fn() },
    log: { debug: jest.fn(), info: jest.fn(), warn: jest.fn(), error: jest.fn() },
    cryptoUtils: { loadOrCreateKey: () => Buffer.alloc(32, 7) },
    isValidContainerId: () => true,
    isTailscaleIP: () => false,
    getTailscaleStatus: async () => null,
  });
}

function captureCookie(setCookie) {
  const headers = {};
  setCookie({ setHeader: (name, value) => { headers[name.toLowerCase()] = value; } }, '24h');
  return headers['set-cookie'];
}

describe('TOTP session cookie scope', () => {
  test('primary login cookie is host-only for custom TLD deployments', () => {
    const session = buildSession();
    const cookie = captureCookie(session.setSessionCookie);

    expect(cookie).toContain('dashcaddy_session=');
    expect(cookie).toContain('HttpOnly');
    expect(cookie).toContain('Secure');
    expect(cookie).toContain('SameSite=Lax');
    expect(cookie).not.toMatch(/(?:^|;)\s*Domain=/i);
  });

  test('SSO exchange uses the same host-only cookie contract', () => {
    const session = buildSession();
    const cookie = captureCookie(session.setHostOnlySessionCookie);

    expect(cookie).toContain('dashcaddy_session=');
    expect(cookie).not.toMatch(/(?:^|;)\s*Domain=/i);
  });

  test('host-bound SSO token can only be redeemed on its intended service host', () => {
    const session = buildSession();
    const wrongHostToken = session.createHandoffToken('plex.sami');
    expect(session.redeemHandoffToken(wrongHostToken, 'chat.sami')).toBe(false);
    expect(session.redeemHandoffToken(wrongHostToken, 'plex.sami')).toBe(false);

    const correctHostToken = session.createHandoffToken('plex.sami');
    expect(session.redeemHandoffToken(correctHostToken, 'plex.sami')).toBe(true);
    expect(session.redeemHandoffToken(correctHostToken, 'plex.sami')).toBe(false);
  });

  test('logout clears the host-only secure cookie', () => {
    const session = buildSession();
    const headers = {};
    session.clearSessionCookie({
      setHeader: (name, value) => { headers[name.toLowerCase()] = value; },
    });

    expect(headers['set-cookie']).toContain('Max-Age=0');
    expect(headers['set-cookie']).toContain('Secure');
    expect(headers['set-cookie']).not.toMatch(/(?:^|;)\s*Domain=/i);
  });
});
