<?php

declare(strict_types=1);

namespace FiloBlu\Refilo\Model;

use RuntimeException;

/**
 *
 */
class RoundingStrategyProvider
{
    /** @var string  */
    public const DEFAULT = 'round_default';

    /**
     * @var \FiloBlu\Refilo\Model\RoundingStrategyInterface[]
     */
    private $roundingStrategy;

    /**
     * @param array $roundingStrategy
     */
    public function __construct(array $roundingStrategy = [])
    {
        $this->roundingStrategy = $roundingStrategy;
    }

    /**
     * @return mixed
     */
    public function getAll()
    {
        return $this->roundingStrategy;
    }

    /**
     * @param string $strategy
     * @return \FiloBlu\Refilo\Model\RoundingStrategyInterface
     * @throws \RuntimeException
     */
    public function get($strategy)
    {
        if (!isset($this->roundingStrategy[$strategy])) {
            throw new RuntimeException("No strategy selected or strategy with name '$strategy' exists");
        }

        return $this->roundingStrategy[$strategy];
    }

    /**
     * Resolve a strategy, falling back to the default one when it is empty or unknown.
     *
     * Used in the pricing/checkout flow so that a misconfigured (empty/invalid) strategy
     * setting never throws and breaks cart/order rounding.
     *
     * @param string|null $strategy
     * @return \FiloBlu\Refilo\Model\RoundingStrategyInterface
     * @throws \RuntimeException
     */
    public function getOrDefault($strategy): RoundingStrategyInterface
    {
        if ($strategy && isset($this->roundingStrategy[$strategy])) {
            return $this->roundingStrategy[$strategy];
        }

        return $this->getDefault();
    }

    /**
     * @return \FiloBlu\Refilo\Model\RoundingStrategyInterface
     * @throws \RuntimeException
     */
    public function getDefault(): RoundingStrategyInterface
    {
        return $this->get(self::DEFAULT);
    }
}