/**
 * Gateway rail HTTP surface — list, health, validate, enforcement hook (supertest).
 * GATEWAY_RAIL_RATE_LIMIT_IN_TEST: see gateway-http-env-setup.ts (jest.gateway-http.config.js).
 */

import request from 'supertest';
import { DbisError, ErrorCode } from '@/shared/types';
import * as gatewayEnforcement from '@/core/gateway/rails/gateway-rails-enforcement';
import { createGatewayHttpTestApp } from '@/__tests__/utils/gateway-http-test-app';

const app = createGatewayHttpTestApp();
const BASE = '/api/v1/gateway';

describe('Gateway rails HTTP', () => {
  const prevEnforce = process.env.SOLACENET_GATEWAY_RAILS_ENFORCE;

  afterEach(() => {
    process.env.SOLACENET_GATEWAY_RAILS_ENFORCE = prevEnforce;
    jest.restoreAllMocks();
  });

  it('GET /rails returns maintainer, adapters, enforcement flag', async () => {
    const res = await request(app).get(`${BASE}/rails`);
    expect(res.status).toBe(200);
    expect(res.body.maintainer).toBe('SolaceNet');
    expect(Array.isArray(res.body.adapters)).toBe(true);
    expect(res.body.adapters).toContain('dbis.adapter.ktt-evidence');
    expect(typeof res.body.enforcementEnabled).toBe('boolean');
  });

  it('GET /rails/:adapterId/health returns 404 for unknown adapter', async () => {
    const res = await request(app).get(`${BASE}/rails/not-a-real-adapter/health`);
    expect(res.status).toBe(404);
    expect(res.body.error).toBe('UNKNOWN_ADAPTER');
  });

  it('GET /rails/dbis.adapter.ktt-evidence/health returns 200', async () => {
    const res = await request(app).get(`${BASE}/rails/dbis.adapter.ktt-evidence/health`);
    expect(res.status).toBe(200);
    expect(res.body.adapterId).toBe('dbis.adapter.ktt-evidence');
  });

  it('POST /rails/dbis.adapter.ktt-evidence/validate returns validation shape', async () => {
    const res = await request(app)
      .post(`${BASE}/rails/dbis.adapter.ktt-evidence/validate`)
      .send({ tenantId: 't1', canonicalInstruction: {} });
    expect(res.status).toBe(200);
    expect(res.body.adapterId).toBe('dbis.adapter.ktt-evidence');
    expect(res.body).toHaveProperty('ok');
  });

  it('returns 403 when enforcement denies capability', async () => {
    process.env.SOLACENET_GATEWAY_RAILS_ENFORCE = '1';
    jest.spyOn(gatewayEnforcement, 'maybeRequireGatewayMicroservices').mockRejectedValue(
      new DbisError(ErrorCode.FORBIDDEN, 'Capability gateway-microservices is not available'),
    );

    const res = await request(app).get(`${BASE}/rails/dbis.adapter.ktt-evidence/health`);
    expect(res.status).toBe(403);
    expect(res.body.code).toBe(ErrorCode.FORBIDDEN);
  });

  it('POST /instructions returns 202 and correlation fields', async () => {
    const res = await request(app)
      .post(`${BASE}/instructions`)
      .send({ tenantId: 't1', amount: '1', currency: 'USD' });
    expect(res.status).toBe(202);
    expect(res.body.status).toBe('RECEIVED');
    expect(res.body.txnId).toBeDefined();
    expect(res.body.correlationId).toBeDefined();
  });
});
