<?php

if (!class_exists('UmbrellaChecksumDictionaryGenerator', false)):
    class UmbrellaChecksumDictionaryGenerator
    {
        /**
         * @var UmbrellaContext
         */
        protected $context;

        /**
         * @var UmbrellaWebSocket
         */
        protected $socket;

        protected $checksumFileHandler;

        public function __construct($params)
        {
            $this->context = $params['context'] ?? null;
            $this->socket = $params['socket'] ?? null;
            $this->openChecksumFile();
        }

        public function closeChecksumFile()
        {
            if (!$this->checksumFileHandler || !is_resource($this->checksumFileHandler)) {
                return;
            }
            fclose($this->checksumFileHandler);
        }

        public function openChecksumFile()
        {
            touch($this->getChecksumPath());
            $this->checksumFileHandler = fopen($this->getChecksumPath(), 'a+');
        }

        public function __destruct()
        {
            $this->closeChecksumFile();
        }

        public function startDirectory()
        {
            if (is_file($this->getChecksumPath())) {
                $this->closeChecksumFile();
                unlink($this->getChecksumPath());
                $this->openChecksumFile();
            }
            fwrite($this->checksumFileHandler, "<?php if(!defined('UMBRELLA_BACKUP_KEY')){  exit; } ?>" . PHP_EOL);
        }

        public function addFile(string $path)
        {
            $path = str_replace($this->context->getBaseDirectory(), '', $path);

            fwrite($this->checksumFileHandler, "$path" . PHP_EOL);
        }

        /**
         * @param string $directory Send the full path of the directory, not the relative path
         */
        public function endDirectory(string $directory)
        {
            if (!is_file($this->getChecksumPath())) {
                return;
            }

            $checksumValue = $this->getChecksumValue();

            if (empty($checksumValue)) {
                return;
            }

            $directory = str_replace($this->context->getBaseDirectory(), '', $directory);

            $directory = $directory === '' ? '/' : $directory;

            $this->socket->sendChecksum($directory, $checksumValue);
        }

        public function getChecksumValue()
        {
            if (!is_file($this->getChecksumPath())) {
                return;
            }

            fseek($this->checksumFileHandler, 0);
            $content = fread($this->checksumFileHandler, filesize($this->getChecksumPath()));

            $content = explode(PHP_EOL, $content);
            array_shift($content);
            sort($content, SORT_STRING);
            $content = implode('', $content);

            if (empty($content)) {
                return;
            }

            return md5($content);
        }

        protected function getChecksumPath()
        {
            return $this->context->getChecksumDirectory() . DIRECTORY_SEPARATOR . 'file-checksum-dictionary.php';
        }
    }
endif;
