<?php declare(strict_types=1);

require_once __DIR__ . '/../storage/QrbStorage.php';

// Helper to write the status file for the web interface.
// The methods of this class do not throw exceptions, but call "die"!
final class QrbProcessStatus
{
    // EOF marker for status
    public  const STATUS_EOF_MARKER = "---EOF---";
    // path to the status file
    private const STATUS_FILE_PATH  = __DIR__ . "/../../data/";
    // name of the status file
    private const STATUS_FILE_NAME  = "qr-bills.status";
    
    // for unit test
    public static function getStatusPath() : string
    {
        return QrbFiles::fixPath(self::STATUS_FILE_PATH);
    }
    
    // public for unit test
    public static function getStatusFullFileName() : string
    {
        return QrbFiles::fixPath(self::STATUS_FILE_PATH . self::STATUS_FILE_NAME);
    }

    private QrbStorage $qrbStorage;
    private string     $statusFileName;

    // Constructs an instance.
    //
    // qrbStorage: all output written to the status file is written to the log as well
    public function __construct(QrbStorage $qrbStorage)
    {
        $this->qrbStorage     = $qrbStorage;
        $this->statusFileName = self::getStatusFullFileName();
        
        $this->createNewStatusFile();
    }

    // Deletes the old status file (if there is one) and creates a new one.
    private function createNewStatusFile() : void
    {
        $this->writeLog("Creating new status file '{$this->statusFileName}'.");
        
        if (file_exists($this->statusFileName) && !unlink($this->statusFileName))
        {
            $this->writeLog("ERROR: Could not delete status file '{$this->statusFileName}'!");
            return;
        }

        if (!file_exists(self::STATUS_FILE_PATH) && !mkdir(self::STATUS_FILE_PATH, 0777, true))
        {
            $this->writeLog("ERROR: Unable to create directory {self::STATUS_FILE_PATH} for status file!");
            return;
        }

        if (($statusFile = fopen($this->statusFileName, "w")) === false)
        {
            $this->writeLog("ERROR: Unable to open status file '{$this->statusFileName}' for write!");
            return;
        }
            
        fclose($statusFile);
    }
    
    // Writes EOF marker into status file.
    function __destruct()
    {
        // write EOF marker into status file
        $this->writeLog("Writing EOF into status file '{$this->statusFileName}'.");
        $this->writeStatus(self::STATUS_EOF_MARKER);
    }
    
    // Writes the message to the status file for the web interface (and to the log as well).
    public function write(string $message) : void
    {
        $this->writeLog($message);
        $this->writeStatus($message);
    }
    
    // Writes the given message to the log.
    private function writeLog(string $message) : void
    {
        $this->qrbStorage->writeLog("=> Status: " . $message);
    }

    // Writes the given message to the status file.
    private function writeStatus(string $message) : void
    {
        if (($statusFile = fopen($this->statusFileName, "a")) === false)
        {
            $this->writeLog("ERROR: Unable to open status file '{$this->statusFileName}' for append");
        }
        else
        {    
            if (fwrite($statusFile, $message . "<br />\n") === false)
            {
                $this->writeLog("ERROR: Unable to write status file '{$this->statusFileName}'");
            }
            else
            {
                if (!fflush($statusFile))
                {
                    $this->writeLog("ERROR: Unable to flush status file '{$this->statusFileName}'");
                }
            }
            
            fclose($statusFile);
        }
    }
}

?>
