import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import Fastify from 'fastify';
import Database from 'better-sqlite3';
import { runMigrations } from '../../db/migrations.js';
import { schedulerRoutes } from '../scheduler-routes.js';
describe('scheduler-routes', () => {
    let app;
    let db;
    beforeEach(async () => {
        db = new Database(':memory:');
        runMigrations(db);
        // Seed a scheduled job
        db.prepare(`
      INSERT INTO scheduled_jobs (squad_name, cron_expression, prompt, status, last_run_at, last_result)
      VALUES (?, ?, ?, ?, ?, ?)
    `).run('finance', '0 9 * * 1', 'Generate report', 'active', '2026-03-14T09:00:00Z', 'success');
        app = Fastify();
        // Fake auth middleware
        app.decorate('requireAuth', async () => { });
        await app.register(schedulerRoutes, { db, schedulerService: null });
    });
    afterEach(async () => {
        await app.close();
        db.close();
    });
    it('GET /api/scheduler should list all scheduled jobs', async () => {
        const res = await app.inject({ method: 'GET', url: '/api/scheduler' });
        expect(res.statusCode).toBe(200);
        const body = res.json();
        expect(body.data).toHaveLength(1);
        expect(body.data[0].squad_name).toBe('finance');
    });
    it('GET /api/scheduler/:squad should return job details', async () => {
        const res = await app.inject({ method: 'GET', url: '/api/scheduler/finance' });
        expect(res.statusCode).toBe(200);
        const body = res.json();
        expect(body.data.squad_name).toBe('finance');
    });
    it('GET /api/scheduler/:squad should return 404 for unknown squad', async () => {
        const res = await app.inject({ method: 'GET', url: '/api/scheduler/unknown' });
        expect(res.statusCode).toBe(404);
    });
    it('POST /api/scheduler should create a scheduled job', async () => {
        const res = await app.inject({
            method: 'POST',
            url: '/api/scheduler',
            payload: {
                squad_name: 'marketing',
                cron_expression: '0 8 * * *',
                prompt: 'Send daily digest',
                timezone: 'America/Sao_Paulo',
                timeout_minutes: 15,
            },
        });
        expect(res.statusCode).toBe(201);
        const body = res.json();
        expect(body.data.squad_name).toBe('marketing');
        expect(body.data.cron_expression).toBe('0 8 * * *');
        expect(body.data.prompt).toBe('Send daily digest');
        expect(body.data.timezone).toBe('America/Sao_Paulo');
        expect(body.data.timeout_minutes).toBe(15);
        expect(body.data.status).toBe('active');
    });
    it('POST /api/scheduler should update existing job', async () => {
        const res = await app.inject({
            method: 'POST',
            url: '/api/scheduler',
            payload: {
                squad_name: 'finance',
                cron_expression: '0 10 * * 2',
                prompt: 'Updated report prompt',
            },
        });
        expect(res.statusCode).toBe(201);
        const body = res.json();
        expect(body.data.cron_expression).toBe('0 10 * * 2');
        expect(body.data.prompt).toBe('Updated report prompt');
        // Should still be only one entry for finance
        const list = await app.inject({ method: 'GET', url: '/api/scheduler' });
        const allJobs = list.json().data;
        const financeJobs = allJobs.filter((j) => j.squad_name === 'finance');
        expect(financeJobs).toHaveLength(1);
    });
    it('POST /api/scheduler should reject missing squad_name', async () => {
        const res = await app.inject({
            method: 'POST',
            url: '/api/scheduler',
            payload: { cron_expression: '0 9 * * *', prompt: 'test' },
        });
        expect(res.statusCode).toBe(400);
    });
    it('POST /api/scheduler should reject missing cron_expression', async () => {
        const res = await app.inject({
            method: 'POST',
            url: '/api/scheduler',
            payload: { squad_name: 'test', prompt: 'test' },
        });
        expect(res.statusCode).toBe(400);
    });
    it('POST /api/scheduler should reject missing prompt', async () => {
        const res = await app.inject({
            method: 'POST',
            url: '/api/scheduler',
            payload: { squad_name: 'test', cron_expression: '0 9 * * *' },
        });
        expect(res.statusCode).toBe(400);
    });
    it('GET /api/scheduler/:squad/history should return filtered activities', async () => {
        // Insert a schedule activity
        db.prepare(`
      INSERT INTO squad_activities (id, squad_code, started_at, status, triggered_by, created_at, attempt)
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `).run('act-1', 'finance', '2026-03-14T09:00:00Z', 'completed', 'schedule', '2026-03-14T09:00:00Z', 1);
        // Insert a dashboard activity (should not appear)
        db.prepare(`
      INSERT INTO squad_activities (id, squad_code, started_at, status, triggered_by, created_at, attempt)
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `).run('act-2', 'finance', '2026-03-14T10:00:00Z', 'completed', 'dashboard', '2026-03-14T10:00:00Z', 1);
        const res = await app.inject({ method: 'GET', url: '/api/scheduler/finance/history' });
        expect(res.statusCode).toBe(200);
        const body = res.json();
        expect(body.data).toHaveLength(1);
        expect(body.data[0].triggered_by).toBe('schedule');
    });
    it('GET /api/scheduler/:squad/history should return all execution fields', async () => {
        db.prepare(`
      INSERT INTO squad_activities (id, squad_code, started_at, finished_at, duration_ms, status, user_message, result_summary, triggered_by, created_at, attempt)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    `).run('act-full', 'finance', '2026-03-14T09:00:00Z', '2026-03-14T09:02:30Z', 150000, 'completed', 'Generate report', 'Report generated successfully', 'schedule', '2026-03-14T09:00:00Z', 1);
        const res = await app.inject({ method: 'GET', url: '/api/scheduler/finance/history' });
        expect(res.statusCode).toBe(200);
        const act = res.json().data[0];
        expect(act.id).toBe('act-full');
        expect(act.started_at).toBe('2026-03-14T09:00:00Z');
        expect(act.finished_at).toBe('2026-03-14T09:02:30Z');
        expect(act.duration_ms).toBe(150000);
        expect(act.status).toBe('completed');
        expect(act.result_summary).toBe('Report generated successfully');
        expect(act.attempt).toBe(1);
    });
    it('GET /api/scheduler/:squad/history should order by most recent first', async () => {
        db.prepare(`
      INSERT INTO squad_activities (id, squad_code, started_at, status, triggered_by, created_at, attempt)
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `).run('act-old', 'finance', '2026-03-13T09:00:00Z', 'completed', 'schedule', '2026-03-13T09:00:00Z', 1);
        db.prepare(`
      INSERT INTO squad_activities (id, squad_code, started_at, status, triggered_by, created_at, attempt)
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `).run('act-new', 'finance', '2026-03-14T09:00:00Z', 'failed', 'schedule', '2026-03-14T09:00:00Z', 1);
        const res = await app.inject({ method: 'GET', url: '/api/scheduler/finance/history' });
        const data = res.json().data;
        expect(data).toHaveLength(2);
        expect(data[0].id).toBe('act-new');
        expect(data[1].id).toBe('act-old');
    });
    it('GET /api/scheduler/:squad/history should respect limit parameter', async () => {
        for (let i = 0; i < 5; i++) {
            db.prepare(`
        INSERT INTO squad_activities (id, squad_code, started_at, status, triggered_by, created_at, attempt)
        VALUES (?, ?, ?, ?, ?, ?, ?)
      `).run(`act-${i}`, 'finance', `2026-03-1${i}T09:00:00Z`, 'completed', 'schedule', `2026-03-1${i}T09:00:00Z`, 1);
        }
        const res = await app.inject({ method: 'GET', url: '/api/scheduler/finance/history?limit=2' });
        expect(res.json().data).toHaveLength(2);
    });
});
//# sourceMappingURL=scheduler-routes.test.js.map