<?php

declare (strict_types=1);
namespace Mollie\Inpsyde\Modularity\Properties;

class BaseProperties implements Properties
{
    protected ?bool $isDebug = null;
    protected string $baseName;
    protected string $basePath;
    protected ?string $baseUrl;
    /** @var array<string, mixed> */
    protected array $properties;
    /**
     * @param string $baseName
     * @param string $basePath
     * @param string|null $baseUrl
     * @param array<string, mixed> $properties
     */
    protected function __construct(string $baseName, string $basePath, ?string $baseUrl = null, array $properties = [])
    {
        $baseName = $this->sanitizeBaseName($baseName);
        $basePath = trailingslashit($basePath);
        if ($baseUrl !== null) {
            $baseUrl = trailingslashit($baseUrl);
        }
        $this->baseName = $baseName;
        $this->basePath = $basePath;
        $this->baseUrl = $baseUrl;
        $this->properties = array_replace(Properties::DEFAULT_PROPERTIES, $properties);
    }
    /**
     * @param string $name
     *
     * @return lowercase-string
     */
    protected function sanitizeBaseName(string $name): string
    {
        if (substr_count($name, '/')) {
            $name = dirname($name);
        }
        return strtolower(pathinfo($name, \PATHINFO_FILENAME));
    }
    /**
     * @return string
     */
    public function baseName(): string
    {
        return $this->baseName;
    }
    /**
     * @return string
     */
    public function basePath(): string
    {
        return $this->basePath;
    }
    /**
     * @return string|null
     */
    public function baseUrl(): ?string
    {
        return $this->baseUrl;
    }
    /**
     * @return string
     */
    public function author(): string
    {
        return (string) $this->get(self::PROP_AUTHOR);
    }
    /**
     * @return string
     */
    public function authorUri(): string
    {
        return (string) $this->get(self::PROP_AUTHOR_URI);
    }
    /**
     * @return string
     */
    public function description(): string
    {
        return (string) $this->get(self::PROP_DESCRIPTION);
    }
    /**
     * @return string
     */
    public function textDomain(): string
    {
        return (string) $this->get(self::PROP_TEXTDOMAIN);
    }
    /**
     * @return string
     */
    public function domainPath(): string
    {
        return (string) $this->get(self::PROP_DOMAIN_PATH);
    }
    /**
     * @return string
     */
    public function name(): string
    {
        return (string) $this->get(self::PROP_NAME);
    }
    /**
     * @return string
     */
    public function uri(): string
    {
        return (string) $this->get(self::PROP_URI);
    }
    /**
     * @return string
     */
    public function version(): string
    {
        return (string) $this->get(self::PROP_VERSION);
    }
    /**
     * @return string|null
     */
    public function requiresWp(): ?string
    {
        $value = $this->get(self::PROP_REQUIRES_WP);
        return $value !== '' && is_string($value) ? $value : null;
    }
    /**
     * @return string|null
     */
    public function requiresPhp(): ?string
    {
        $value = $this->get(self::PROP_REQUIRES_PHP);
        return $value !== '' && is_string($value) ? $value : null;
    }
    /**
     * @return string[]
     */
    public function tags(): array
    {
        return (array) $this->get(self::PROP_TAGS);
    }
    /**
     * @param string $key
     * @param mixed $default
     *
     * @return mixed
     */
    public function get(string $key, $default = null)
    {
        return $this->properties[$key] ?? $default;
    }
    /**
     * @param string $key
     *
     * @return bool
     */
    public function has(string $key): bool
    {
        return isset($this->properties[$key]);
    }
    /**
     * @return bool
     * @see Properties::isDebug()
     */
    public function isDebug(): bool
    {
        if ($this->isDebug === null) {
            $this->isDebug = defined('WP_DEBUG') && \WP_DEBUG;
        }
        return $this->isDebug;
    }
}
