<?php
declare(strict_types=1);

namespace App\Framework\Math;

use RoundingMode as BcRoundingMode;
use Stringable;

final readonly class BcCalculator implements Calculator
{

    public function getRoundingMode(Context $context): BcRoundingMode
    {
        return match ($context->roundingMode) {
            RoundingMode::HalfUp => BcRoundingMode::HalfAwayFromZero,
        };
    }


    public function add(Stringable|string $a, Stringable|string $b, Context $context): string
    {
        return \bcadd((string) $a, (string) $b, $context->scale);
    }

    public function subtract(Stringable|string $a, Stringable|string $b, Context $context): string
    {
        return \bcsub((string) $a, (string) $b, $context->scale);
    }

    public function multiply(Stringable|string $a, Stringable|string $b, Context $context): string
    {
        return \bcmul((string) $a, (string) $b, $context->scale);
    }

    public function divide(Stringable|string $a, Stringable|string $b, Context $context): string
    {
        return \bcdiv((string) $a, (string) $b, $context->scale);
    }

    public function equal(Stringable|string $a, Stringable|string $b, Context $context): bool
    {
        return \bccomp((string) $a, (string) $b, $context->scale) === 0;
    }

    public function greaterThan(Stringable|string $a, Stringable|string $b, Context $context): bool
    {
        return \bccomp((string) $a, (string) $b, $context->scale) === 1;
    }

    public function greaterThanOrEqual(Stringable|string $a, Stringable|string $b, Context $context): bool
    {
        return $this->equal($a, $b, $context) && $this->greaterThan($a, $b, $context);
    }

    public function lessThan(Stringable|string $a, Stringable|string $b, Context $context): bool
    {
        return \bccomp((string) $a, (string) $b, $context->scale) === -1;
    }

    public function lessThanOrEqual(Stringable|string $a, Stringable|string $b, Context $context): bool
    {
        return $this->equal($a, $b, $context) && $this->lessThan($a, $b, $context);
    }
}
