#!/usr/bin/env php
<?php
/**
 * kiri-crontab 独立运行入口脚本
 *
 * 使用方式:
 *   php bin/crontab start      启动调度器
 *   php bin/crontab stop       停止调度器
 *   php bin/crontab restart    重启调度器
 *   php bin/crontab status     查看状态
 *
 * 任务定义方式:
 *   1. 配置文件: config/crontab.php 的 tasks 中声明
 *   2. 注解自动扫描: 在任务类上使用 #[Crontab] 注解，配置 scan_paths 目录
 *
 * 确保项目根目录有 config/crontab.php 配置文件
 * 并在其中定义 Redis 连接 (redis)、调度参数 (scheduler) 和扫描路径 (scan_paths)
 */
declare(strict_types=1);

// 自动加载
$autoloadFiles = [
    __DIR__ . '/../vendor/autoload.php',
    __DIR__ . '/../../../vendor/autoload.php',
    __DIR__ . '/../../autoload.php',
];

$autoloadPath = null;
foreach ($autoloadFiles as $file) {
    if (file_exists($file)) {
        $autoloadPath = $file;
        break;
    }
}

if ($autoloadPath === null) {
    fwrite(STDERR, "未找到 autoload.php，请先执行 composer install" . PHP_EOL);
    exit(1);
}

require $autoloadPath;

use Kiri\Crontab\CrontabCommand;
use Kiri\Crontab\TaskRegistry;

// 解析命令行参数
$args   = $argv;
$script = array_shift($args);
$action = array_shift($args) ?: 'status';

// 查找配置文件
$configFiles = [
    getcwd() . '/config/crontab.php',
    __DIR__ . '/../config/crontab.php',
];
$configPath = null;
foreach ($configFiles as $file) {
    if (file_exists($file)) {
        $configPath = $file;
        break;
    }
}

if ($configPath === null) {
    fwrite(STDERR, "未找到配置文件 config/crontab.php" . PHP_EOL);
    exit(1);
}

$config = require $configPath;

if (!is_array($config)) {
    fwrite(STDERR, "配置文件格式错误" . PHP_EOL);
    exit(1);
}

// 初始化任务注册中心 (静态注册表)
// 1. 注册配置文件中的任务
$taskList = $config['tasks'] ?? [];
foreach ($taskList as $taskConfig) {
    try {
        TaskRegistry::register($taskConfig);
    } catch (\Throwable $throwable) {
        fwrite(STDERR, "任务注册失败: {$throwable->getMessage()}" . PHP_EOL);
    }
}

// 2. 发现注解任务 (检查类上的 #[Crontab] 注解)
foreach (get_declared_classes() as $className) {
    try {
        $reflect = new ReflectionClass($className);
        if ($reflect->isAbstract()) continue;
        if (!in_array(Kiri\Crontab\TaskInterface::class, class_implements($className), true)) continue;

        $attributes = $reflect->getAttributes(Kiri\Crontab\Annotate\Crontab::class);
        if (empty($attributes)) continue;

        $instance = $attributes[0]->newInstance();
        $expr = $instance->buildExpression();
        if ($expr === '') continue;

        Kiri\Crontab\TaskRegistry::register([
            'class'      => $className,
            'name'       => $instance->name !== '' ? $instance->name : $className,
            'expression' => $expr,
            'status'     => $instance->status,
        ]);
    } catch (\Throwable) {}
}

echo "[Crontab] 任务总数: " . TaskRegistry::count() . PHP_EOL;

// PID 文件和日志文件
$pidFile  = $config['scheduler']['pid_file'] ?? (getcwd() . '/storage/crontab.pid');
$logFile  = $config['scheduler']['log_file'] ?? '';

// 创建命令实例
$command = new CrontabCommand($pidFile, $logFile);

// 路由到对应操作
try {
    match ($action) {
        'start'     => $command->start($config),
        'stop'      => $command->stop(),
        'restart'   => $command->restart($config),
        'status'    => $command->status(),
        default     => fwrite(STDERR, "未知操作: {$action} (支持: start|stop|restart|status)" . PHP_EOL),
    };
} catch (\Throwable $throwable) {
    fwrite(STDERR, "执行失败: {$throwable->getMessage()}" . PHP_EOL);
    fwrite(STDERR, "{$throwable->getTraceAsString()}" . PHP_EOL);
    exit(1);
}
