// @vitest-environment node
import { describe, it, expect, beforeEach } from 'vitest';
import express from 'express';
import request from 'supertest';
import { Repository } from '../../db/repository.js';
import { createA2aClientsAdminRouter } from './a2a-clients-admin-api.js';

function appWith(repo: Repository) {
  const app = express();
  app.use(express.json());
  // テストでは admin ユーザーを直接注入（本番は requireAdmin が前段）
  app.use((req, _res, next) => { (req as any).user = { id: 'admin1', role: 'admin' }; next(); });
  app.use('/api/admin/a2a/clients', createA2aClientsAdminRouter(repo, true));
  return app;
}

describe('a2a clients admin API', () => {
  let repo: Repository;
  beforeEach(() => { repo = new Repository(':memory:'); });

  it('registers a public client and returns the generated client_id', async () => {
    const app = appWith(repo);
    const res = await request(app).post('/api/admin/a2a/clients')
      .send({ name: 'Partner', redirect_uris: ['https://partner.example/cb'] });
    expect(res.status).toBe(201);
    expect(res.body.client_id).toBeTruthy();
    expect(res.body.token_endpoint_auth_method).toBe('none');
    expect(repo.getA2aClient(res.body.client_id)?.name).toBe('Partner');
  });

  it('rejects a registration with no redirect_uris', async () => {
    const app = appWith(repo);
    const res = await request(app).post('/api/admin/a2a/clients').send({ name: 'X', redirect_uris: [] });
    expect(res.status).toBe(400);
  });

  it('rejects a non-https redirect uri', async () => {
    const app = appWith(repo);
    const res = await request(app).post('/api/admin/a2a/clients')
      .send({ name: 'X', redirect_uris: ['http://insecure/cb'] });
    expect(res.status).toBe(400);
  });

  it('disables a client', async () => {
    const app = appWith(repo);
    const reg = await request(app).post('/api/admin/a2a/clients')
      .send({ name: 'P', redirect_uris: ['https://p/cb'] });
    const id = reg.body.client_id;
    const res = await request(app).post(`/api/admin/a2a/clients/${id}/disable`);
    expect(res.status).toBe(200);
    expect(repo.getA2aClient(id)?.status).toBe('disabled');
  });

  it('returns 404 when disabling a nonexistent client', async () => {
    const app = appWith(repo);
    const res = await request(app).post('/api/admin/a2a/clients/nonexistent/disable');
    expect(res.status).toBe(404);
  });

  it('lists all clients without secretHash', async () => {
    const app = appWith(repo);
    await request(app).post('/api/admin/a2a/clients')
      .send({ name: 'C1', redirect_uris: ['https://c1/cb'] });
    const res = await request(app).get('/api/admin/a2a/clients');
    expect(res.status).toBe(200);
    expect(res.body.clients).toHaveLength(1);
    expect(res.body.clients[0].secretHash).toBeUndefined();
    expect(res.body.clients[0].name).toBe('C1');
  });
});
