<?php
declare(strict_types=1);

namespace SeoScope\Licensing;

final class LicenseStorage
{
    public function __construct(
        private string $root
    ) {
    }

    public function load(): LicenseState
    {
        $path = $this->statePath();
        if (!is_readable($path)) {
            return new LicenseState('unlicensed', null, null, null, null);
        }
        $raw = @file_get_contents($path);
        if (!is_string($raw) || $raw === '') {
            return new LicenseState('unlicensed', null, null, null, null);
        }
        $data = json_decode($raw, true);
        if (!is_array($data)) {
            return new LicenseState('unlicensed', null, null, null, null);
        }
        return LicenseState::fromArray($data);
    }

    public function save(LicenseState $state): void
    {
        $dir = $this->root . '/storage/app';
        if (!is_dir($dir)) {
            @mkdir($dir, 0775, true);
        }
        $path = $this->statePath();
        $json = json_encode($state->toArray(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        if (!is_string($json)) {
            return;
        }
        @file_put_contents($path, $json);
    }

    public function installId(): string
    {
        $dir = $this->root . '/storage/app';
        if (!is_dir($dir)) {
            @mkdir($dir, 0775, true);
        }
        $path = $dir . '/install_id.txt';
        $id = '';
        if (is_readable($path)) {
            $id = trim((string) @file_get_contents($path));
        }
        if ($id !== '' && preg_match('/^[a-zA-Z0-9-]{16,64}$/', $id)) {
            return $id;
        }
        $id = self::uuidv4();
        @file_put_contents($path, $id);
        return $id;
    }

    private function statePath(): string
    {
        return $this->root . '/storage/app/license.json';
    }

    private static function uuidv4(): string
    {
        $b = random_bytes(16);
        $b[6] = chr((ord($b[6]) & 0x0f) | 0x40);
        $b[8] = chr((ord($b[8]) & 0x3f) | 0x80);
        $hex = bin2hex($b);
        return substr($hex, 0, 8) . '-' . substr($hex, 8, 4) . '-' . substr($hex, 12, 4) . '-' . substr($hex, 16, 4) . '-' . substr($hex, 20, 12);
    }
}

