import test from 'node:test';
import assert from 'node:assert/strict';
import {
  hasReservedRestartVerification,
  summarizeRestartReservationAutomationWork,
  summarizeRestartReservationCodexWork,
} from './server-restart-reservation-service.js';

const reservationStartedAt = '2026-05-06T00:00:00.000Z';

test('hasReservedRestartVerification keeps test restart pending until a new startedAt and build timestamp exist', () => {
  assert.equal(
    hasReservedRestartVerification(
      'test',
      {
        availability: 'online',
        startedAt: '2026-05-05T23:59:40.000Z',
        runningBuiltAt: '2026-05-06T00:00:05.000Z',
        runningVersion: null,
        buildRequired: false,
        updateAvailable: false,
      },
      reservationStartedAt,
    ),
    false,
  );

  assert.equal(
    hasReservedRestartVerification(
      'test',
      {
        availability: 'online',
        startedAt: '2026-05-06T00:00:03.000Z',
        runningBuiltAt: null,
        runningVersion: null,
        buildRequired: false,
        updateAvailable: false,
      },
      reservationStartedAt,
    ),
    false,
  );

  assert.equal(
    hasReservedRestartVerification(
      'test',
      {
        availability: 'online',
        startedAt: '2026-05-06T00:00:03.000Z',
        runningBuiltAt: '2026-05-06T00:00:05.000Z',
        runningVersion: null,
        buildRequired: false,
        updateAvailable: false,
      },
      reservationStartedAt,
    ),
    true,
  );

  assert.equal(
    hasReservedRestartVerification(
      'test',
      {
        availability: 'online',
        startedAt: '2026-05-06T00:00:03.000Z',
        runningBuiltAt: '2026-05-06T00:00:05.000Z',
        runningVersion: null,
        buildRequired: true,
        updateAvailable: false,
      },
      reservationStartedAt,
    ),
    true,
  );
});

test('hasReservedRestartVerification keeps work-server restart pending until new runtime and build info are ready', () => {
  assert.equal(
    hasReservedRestartVerification(
      'work-server',
      {
        availability: 'online',
        startedAt: '2026-05-06T00:00:03.000Z',
        runningBuiltAt: '2026-05-06T00:00:04.000Z',
        runningVersion: null,
        buildRequired: false,
        updateAvailable: false,
      },
      reservationStartedAt,
    ),
    true,
  );

  assert.equal(
    hasReservedRestartVerification(
      'work-server',
      {
        availability: 'online',
        startedAt: '2026-05-06T00:00:03.000Z',
        runningBuiltAt: null,
        runningVersion: null,
        buildRequired: false,
        updateAvailable: false,
      },
      reservationStartedAt,
    ),
    false,
  );

  assert.equal(
    hasReservedRestartVerification(
      'work-server',
      {
        availability: 'online',
        startedAt: '2026-05-06T00:00:03.000Z',
        runningBuiltAt: '2026-05-06T00:00:04.000Z',
        runningVersion: 'build-2',
        buildRequired: false,
        updateAvailable: true,
      },
      reservationStartedAt,
    ),
    true,
  );

  assert.equal(
    hasReservedRestartVerification(
      'work-server',
      {
        availability: 'online',
        startedAt: '2026-05-06T00:00:03.000Z',
        runningBuiltAt: '2026-05-06T00:00:04.000Z',
        runningVersion: '0.1.0@2026-05-06T00:00:04.000Z',
        buildRequired: true,
        updateAvailable: true,
      },
      reservationStartedAt,
    ),
    true,
  );
});

test('summarizeRestartReservationAutomationWork ignores pending requests that were not accepted into automation', () => {
  const summary = summarizeRestartReservationAutomationWork([
    {
      requestItems: [
        {
          id: 1,
          boardPostId: 1,
          sequence: 1,
          title: 'pending',
          content: '',
          planItemId: null,
          automationReceivedAt: null,
          workflowState: 'pending',
          status: 'pending',
          statusLabel: '미접수',
          planStatus: null,
          workerStatus: null,
          lastError: null,
          createdAt: '',
          updatedAt: '',
        },
        {
          id: 2,
          boardPostId: 1,
          sequence: 2,
          title: 'waiting',
          content: '',
          planItemId: 10,
          automationReceivedAt: '2026-05-06T00:00:00.000Z',
          workflowState: 'waiting',
          status: 'waiting',
          statusLabel: '선행 대기',
          planStatus: null,
          workerStatus: null,
          lastError: null,
          createdAt: '',
          updatedAt: '',
        },
        {
          id: 3,
          boardPostId: 1,
          sequence: 3,
          title: 'running',
          content: '',
          planItemId: 11,
          automationReceivedAt: '2026-05-06T00:00:00.000Z',
          workflowState: 'registered',
          status: 'in_progress',
          statusLabel: '진행중',
          planStatus: '작업중',
          workerStatus: '자동작업중',
          lastError: null,
          createdAt: '',
          updatedAt: '',
        },
      ],
    },
  ]);

  assert.deepEqual(summary, {
    running: 1,
    queued: 1,
  });
});

test('summarizeRestartReservationCodexWork keeps the reservation requester counted while work is still running', () => {
  const summary = summarizeRestartReservationCodexWork(
    {
      running: [
        { sessionId: 'session-a' },
        { sessionId: 'session-b' },
      ],
      queued: [
        { sessionId: 'session-a' },
        { sessionId: 'session-c' },
      ],
    },
    {
      sessionClientIds: new Map([
        ['session-a', 'client-a'],
        ['session-b', 'client-b'],
        ['session-c', 'client-c'],
      ]),
    },
  );

  assert.deepEqual(summary, {
    running: 2,
    queued: 2,
  });
});

test('summarizeRestartReservationCodexWork keeps the current client counted when no exclusion is provided', () => {
  const summary = summarizeRestartReservationCodexWork(
    {
      running: [
        { sessionId: 'session-a' },
        { sessionId: 'session-b' },
      ],
      queued: [
        { sessionId: 'session-a' },
        { sessionId: 'session-c' },
      ],
    },
    {
      sessionClientIds: new Map([
        ['session-a', 'client-a'],
        ['session-b', 'client-b'],
        ['session-c', 'client-c'],
      ]),
    },
  );

  assert.deepEqual(summary, {
    running: 2,
    queued: 2,
  });
});
