<?php

declare(strict_types=1);

namespace app\common\service;

/**
 * 工单同步互斥锁（基于 runtime 文件锁，不依赖 Cache/Redis 扩展）
 */
class SplitTicketSyncLockService
{
    private const LOCK_TTL = 1800;

    /**
     * 尝试获取锁
     */
    public function acquire(int $ticketId): bool
    {
        $path = $this->lockPath($ticketId);
        if ($this->isStaleLock($path)) {
            @unlink($path);
        }
        if (is_file($path)) {
            return false;
        }
        $payload = json_encode([
            'ticket_id' => $ticketId,
            'pid'       => getmypid(),
            'time'      => time(),
        ], JSON_UNESCAPED_UNICODE);
        $written = @file_put_contents($path, $payload, LOCK_EX);
        return $written !== false;
    }

    /**
     * 释放锁
     */
    public function release(int $ticketId): void
    {
        $path = $this->lockPath($ticketId);
        if (is_file($path)) {
            @unlink($path);
        }
    }

    private function lockPath(int $ticketId): string
    {
        $runtime = defined('RUNTIME_PATH') ? RUNTIME_PATH : (dirname(__DIR__, 3) . '/runtime/');
        $dir = $runtime . 'split_ticket_sync/';
        if (!is_dir($dir)) {
            @mkdir($dir, 0755, true);
        }
        return $dir . $ticketId . '.lock';
    }

    private function isStaleLock(string $path): bool
    {
        if (!is_file($path)) {
            return false;
        }
        $mtime = (int) @filemtime($path);
        return $mtime > 0 && (time() - $mtime) > self::LOCK_TTL;
    }
}
