<?php

declare(strict_types=1);

namespace Seka\Portal\Modul\Statistiky\Services\Import;

use Exception;
use InvalidArgumentException;

/**
 * Class File
 *
 * @package Seka\Portal\Modul\Statistiky\Services\Import
 */
final class File
{
    /**
     * @var string
     */
    private string $fileName;

    /**
     * @var null
     */
    private $resource = null;

    /**
     * File constructor.
     *
     * @param string $fileName
     * @throws \InvalidArgumentException
     */
    public function __construct(string $fileName)
    {
        $this->fileName = $fileName;

        $this->checkExistence();
    }

    /**
     * @return void
     * @throws \InvalidArgumentException
     */
    public function check(): void
    {
        $this->checkExistence();
        $this->checkFileSize();
    }

    /**
     * @return false|resource
     */
    public function open()
    {
        $this->checkExistence();

        if (is_null($this->resource) || !is_resource($this->resource)) {
            $this->resource = fopen($this->fileName, 'r');
        }

        return $this->resource;
    }

    /**
     *
     */
    public function close(): void
    {
        if (is_null($this->resource)) {
            return;
        }

        fclose($this->resource);
    }

    /**
     * @return array|false
     */
    public function content()
    {
        $this->checkExistence();

        return file($this->fileName);
    }

    /**
     * @param string $path
     *
     * @return void
     * @throws \Exception|\InvalidArgumentException
     */
    public function move(string $path): void
    {
        $this->checkExistence();

        if (!is_dir($path)) {
            throw new InvalidArgumentException(sprintf('Cielovy adresar cesty "%s" neexistuje.', $path));
        }

        if (copy($this->fileName, join(DIRECTORY_SEPARATOR, [$path, $this->name()]))) {
            unlink($this->fileName);

            return;
        }

        throw new Exception(sprintf('Subor "%s" sa nepodarilo presunut do adresara "%s".', $this->fileName, $path));
    }

    /**
     * @return string
     */
    public function path(): string
    {
        return dirname($this->fileName);
    }

    /**
     * @return string
     */
    public function name(): string
    {
        return basename($this->fileName);
    }

    /**
     * @return string
     */
    public function fileName(): string
    {
        return $this->fileName;
    }

    /**
     * @return int
     */
    public function size(): int
    {
        return filesize($this->fileName) ?? 0;
    }

    /**
     * @return void
     * @throws \InvalidArgumentException
     */
    private function checkExistence(): void
    {
        if (!file_exists($this->fileName) || !is_file($this->fileName)) {
            throw new InvalidArgumentException(sprintf('Subor "%s" sa nepodarilo spracovat, subor neexistuje alebo nie je pristupny pre citanie.', $this->fileName));
        }
    }

    /**
     * @return void
     * @throws \InvalidArgumentException
     */
    private function checkFileSize(): void
    {
        if (!filesize($this->fileName)) {
            throw new InvalidArgumentException(sprintf('Subor "%s" neobsahuje ziadne udaje, je prazdny.', $this->fileName));
        }
    }

    /**
     * @param string $path
     *
     * @return bool
     */
    public static function isEmpty(string $path): bool
    {
        return ! (bool) filesize($path);
    }

    /**
     * @param string $path
     *
     * @return bool
     */
    public static function isFile(string $path): bool
    {
        return is_file($path);
    }

    /**
     * @param string $path
     *
     * @return bool
     */
    public static function isDir(string $path): bool
    {
        return is_dir($path);
    }
}
