<?php 
 
/* 
 * This file is part of Chevere. 
 * 
 * (c) Rodolfo Berrios <rodolfo@chevere.org> 
 * 
 * For the full copyright and license information, please view the LICENSE 
 * file that was distributed with this source code. 
 */ 
 
declare(strict_types=1); 
 
namespace Chevere\Xr; 
 
use function Chevere\Filesystem\filePhpReturnForPath; 
use Chevere\Filesystem\Interfaces\DirInterface; 
use function Chevere\Type\typeArray; 
use Chevere\Xr\Interfaces\XrClientInterface; 
use Chevere\Xr\Interfaces\XrCurlInterface; 
use Chevere\Xr\Interfaces\XrInterface; 
use Throwable; 
 
final class Xr implements XrInterface 
{ 
    private XrClientInterface $client; 
 
    private DirInterface $configDir; 
 
    private string $configFile = ''; 
 
    private array $configNames = ['xr.php']; 
 
    private XrCurlInterface $curl; 
 
    public function __construct( 
        private bool $enable = true, 
        private string $host = 'localhost', 
        private int $port = 27420 
    ) { 
        $this->curl = new XrCurl(); 
        $this->setClient(); 
    } 
 
    public function withConfigDir(DirInterface $configDir): XrInterface 
    { 
        $new = clone $this; 
        $new->configDir = $configDir; 
        $new->configFile = $new->getConfigFile(); 
        if ($new->configFile !== '') { 
            $new->setConfigFromFile(); 
        } 
        $new->setClient(); 
 
        return $new; 
    } 
 
    public function enable(): bool 
    { 
        return $this->enable; 
    } 
 
    public function client(): XrClientInterface 
    { 
        return $this->client; 
    } 
 
    public function host(): string 
    { 
        return $this->host; 
    } 
 
    public function port(): int 
    { 
        return $this->port; 
    } 
 
    private function setConfigFromFile(): void 
    { 
        try { 
            $return = filePhpReturnForPath($this->configFile) 
                ->varType(typeArray()); 
            foreach (['enable', 'host', 'port'] as $prop) { 
                $this->{$prop} = $return[$prop] ?? $this->{$prop}; 
            } 
        } 
        // @codeCoverageIgnoreStart 
        catch (Throwable) { 
            // Ignore to use defaults 
        } 
        // @codeCoverageIgnoreEnd 
    } 
 
    private function getConfigFile(): string 
    { 
        $configDirectory = $this->configDir->path()->__toString(); 
        while (is_dir($configDirectory)) { 
            foreach ($this->configNames as $configName) { 
                $configFullPath = $configDirectory . $configName; 
                if (file_exists($configFullPath)) { 
                    return $configFullPath; 
                } 
            } 
            $parentDirectory = dirname($configDirectory) . DIRECTORY_SEPARATOR; 
            if ($parentDirectory === $configDirectory) { 
                return ''; 
            } 
            $configDirectory = $parentDirectory; 
        } 
 
        return ''; // @codeCoverageIgnore 
    } 
 
    private function setClient(): void 
    { 
        $this->client = (new XrClient( 
            host: $this->host, 
            port: $this->port, 
        ))->withCurl($this->curl); 
    } 
} 
 
 |