<?php
/*
 * Copyright 2026 Alessandro Chiapparini <sprint_planer_web@chiapparini.org>
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * See the LICENSE file in the project root for the full license text.
 */

declare(strict_types=1);

namespace App\Tests\Controllers;

use App\Controllers\SprintController;
use App\Tests\TestCase;
use ReflectionMethod;

/**
 * Pure-static guards on SprintController. Mirrors ImportControllerTest:
 * exercise the bits that do not need PDO or session wiring.
 */
final class SprintControllerTest extends TestCase
{
    public function testWeeksBetweenInclusiveSameDayIsOneWeek(): void
    {
        $this->assertSame(1, self::call('weeksBetween', '2026-01-05', '2026-01-05'));
    }

    public function testWeeksBetweenSpansFullCalendarWeeks(): void
    {
        // Mon → Fri of the same week → 1 week.
        $this->assertSame(1, self::call('weeksBetween', '2026-01-05', '2026-01-09'));
        // Mon → Sun (end of the same week, +6 days) → 1 week.
        $this->assertSame(1, self::call('weeksBetween', '2026-01-05', '2026-01-11'));
        // Mon → Mon next week (+7 days) flips to 2 weeks.
        $this->assertSame(2, self::call('weeksBetween', '2026-01-05', '2026-01-12'));
        // Mon → Fri three weeks later → 3 weeks.
        $this->assertSame(3, self::call('weeksBetween', '2026-01-05', '2026-01-23'));
    }

    public function testWeeksBetweenClampsToOneWhenDatesAreReversed(): void
    {
        $this->assertSame(1, self::call('weeksBetween', '2026-01-12', '2026-01-05'));
    }

    private static function call(string $method, mixed ...$args): mixed
    {
        $r = new ReflectionMethod(SprintController::class, $method);
        $r->setAccessible(true);
        return $r->invoke(null, ...$args);
    }

    /**
     * R01-N24: the per-batch list cap is a drift-sensitive number — bumping
     * it has security implications (memory + DB pressure under attacker
     * load) and operator implications (existing tooling that batches near
     * the cap may break). A future refactor that tweaks it must update
     * REVIEW_01.md §R01-N24 in the same commit.
     */
    public function testMaxBatchItemsConstant(): void
    {
        $this->assertSame(5000, SprintController::MAX_BATCH_ITEMS);
    }
}
