<?php
namespace Misuzu\Config;

use InvalidArgumentException;

class ScopedConfig implements IConfig {
    private IConfig $config;
    private string $prefix;

    // update this to : at some point, would need adjustment of the live site's config
    private const SCOPE_CHAR = '.';

    public function __construct(IConfig $config, string $prefix) {
        if($prefix === '')
            throw new InvalidArgumentException('$prefix may not be empty.');
        if(!str_ends_with($prefix, self::SCOPE_CHAR))
            $prefix .= self::SCOPE_CHAR;

        $this->config = $config;
        $this->prefix = $prefix;
    }

    private function getName(string $name): string {
        return $this->prefix . $name;
    }

    public function scopeTo(string $prefix): IConfig {
        return $this->config->scopeTo($this->getName($prefix));
    }

    public function getNames(): array {
        $orig = $this->config->getNames();
        $pfxLength = strlen($this->prefix);
        $filter = [];

        foreach($orig as $name)
            if(str_starts_with($name, $this->prefix))
                $filter[] = substr($name, $pfxLength);

        return $filter;
    }

    public function getValue(string $name, string $type = CfgType::T_ANY, $default = null): mixed {
        return $this->config->getValue($this->getName($name), $type, $default);
    }

    public function hasValue(string $name): bool {
        return $this->config->hasValue($this->getName($name));
    }

    public function setValue(string $name, $value, bool $save = true): void {
        $this->config->setValue($this->getName($name), $value, $save);
    }

    public function removeValue(string $name, bool $save = true): void {
        $this->config->removeValue($this->getName($name), $save);
    }
}
