import { HttpClient, provideHttpClient, withInterceptors } from '@angular/common/http';
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import {
  HTTP_OBSERVATION_CLOCK,
  HTTP_OBSERVER,
  HttpObservation,
  loggingInterceptor,
} from './logging.interceptor';

describe('loggingInterceptor', () => {
  let http: HttpClient;
  let controller: HttpTestingController;
  let started: HttpObservation[];
  let completed: HttpObservation[];

  beforeEach(() => {
    started = [];
    completed = [];
    const ticks = [10, 25];

    TestBed.configureTestingModule({
      providers: [
        provideHttpClient(withInterceptors([loggingInterceptor])),
        provideHttpClientTesting(),
        {
          provide: HTTP_OBSERVER,
          useValue: {
            started: (value: HttpObservation) => started.push(value),
            completed: (value: HttpObservation) => completed.push(value),
          },
        },
        { provide: HTTP_OBSERVATION_CLOCK, useValue: () => ticks.shift() ?? 25 },
      ],
    });
    http = TestBed.inject(HttpClient);
    controller = TestBed.inject(HttpTestingController);
  });

  afterEach(() => controller.verify());

  it('reports safe request metadata without query strings, headers or bodies', () => {
    http.post('/api/payments?token=must-not-leak', { password: 'must-not-leak' }, {
      headers: { Authorization: 'Bearer must-not-leak' },
    }).subscribe();

    controller.expectOne('/api/payments?token=must-not-leak').flush({}, { status: 201, statusText: 'Created' });

    expect(started).toEqual([{ method: 'POST', path: '/api/payments' }]);
    expect(completed).toEqual([{
      method: 'POST',
      path: '/api/payments',
      status: 201,
      durationMs: 15,
    }]);
    expect(JSON.stringify({ started, completed })).not.toContain('must-not-leak');
  });
});
