<?php

namespace QUI\Cache;

use QUI;

use function basename;
use function chmod;
use function dirname;
use function file_exists;
use function fileperms;
use function file_put_contents;
use function rename;
use function strlen;
use function tempnam;
use function umask;
use function unlink;

use const LOCK_EX;

final class CacheFileWriter
{
    /**
     * @throws QUI\Exception
     */
    public static function write(string $cacheFile, string $content): void
    {
        $permissions = 0666 & ~umask();

        if (file_exists($cacheFile)) {
            $currentPermissions = fileperms($cacheFile);

            if ($currentPermissions !== false) {
                $permissions = $currentPermissions & 0777;
            }
        }

        $tempFile = tempnam(dirname($cacheFile), basename($cacheFile) . '.');

        if ($tempFile === false) {
            throw new QUI\Exception('Could not create temporary cache file');
        }

        $bytesWritten = file_put_contents($tempFile, $content, LOCK_EX);

        if ($bytesWritten !== strlen($content)) {
            unlink($tempFile);
            throw new QUI\Exception('Could not write temporary cache file');
        }

        if (!chmod($tempFile, $permissions)) {
            unlink($tempFile);
            throw new QUI\Exception('Could not set cache file permissions');
        }

        if (!rename($tempFile, $cacheFile)) {
            unlink($tempFile);
            throw new QUI\Exception('Could not publish cache file');
        }
    }
}
