<?php

declare(strict_types=1);

namespace NoahVet\Reef\Test\A_Unit\Domain\Common;

use NoahVet\Reef\Test\A_Unit\Fixture\Enum\IntegerEnumFixture;
use NoahVet\Reef\Test\A_Unit\Fixture\Enum\StringEnumFixture;
use PHPUnit\Framework\TestCase;

final class EnumTraitTest extends TestCase
{
    public function testGetEnumFromName(): void
    {
        $string = StringEnumFixture::getEnumFromName('NAME');
        $integer = IntegerEnumFixture::getEnumFromName('NAME');

        self::assertSame('VALUE', $string->value);
        self::assertSame(0, $integer->value);
    }

    public function testGetEnumFromValue(): void
    {
        $string = StringEnumFixture::getEnumFromValue('VALUE');
        $integer = IntegerEnumFixture::getEnumFromValue(0);

        self::assertSame('NAME', $string->name);
        self::assertSame('NAME', $integer->name);
    }

    public function testGetNameFromValue(): void
    {
        $stringName = StringEnumFixture::getNameFromValue('VALUE');
        $integerName = IntegerEnumFixture::getNameFromValue(0);

        self::assertSame('NAME', $stringName);
        self::assertSame('NAME', $integerName);

        $this->expectException(\ValueError::class);
        $this->expectExceptionMessage(
            "The enum value 99 doesn't exist. The supported enum values are [0].",
        );
        IntegerEnumFixture::getNameFromValue(99);

        $this->expectException(\ValueError::class);
        $this->expectExceptionMessage(
            "The enum value BAD_VALUE doesn't exist. The supported enum values are ['VALUE'].",
        );
        StringEnumFixture::getNameFromValue('BAD_VALUE');
    }

    public function testGetValueFromName(): void
    {
        $string = StringEnumFixture::getValueFromName('NAME');
        $integer = IntegerEnumFixture::getValueFromName('NAME');

        self::assertSame('VALUE', $string);
        self::assertSame(0, $integer);

        $this->expectException(\ValueError::class);
        $this->expectExceptionMessage(
            "The enum name BAD_NAME doesn't exist. The supported enum names are [0].",
        );
        IntegerEnumFixture::getValueFromName('BAD_NAME');

        $this->expectException(\ValueError::class);
        $this->expectExceptionMessage(
            "The enum name BAD_NAME doesn't exist. The supported enum names are ['NAME'].",
        );
        StringEnumFixture::getValueFromName('BAD_NAME');
    }

    public function testHasName(): void
    {
        $string = StringEnumFixture::hasName('NAME');
        $integer = IntegerEnumFixture::hasName('NAME');
        $badString = StringEnumFixture::hasName('BAD_NAME');
        $badInteger = IntegerEnumFixture::hasName('BAD_NAME');

        self::assertTrue($string);
        self::assertTrue($integer);
        self::assertFalse($badString);
        self::assertFalse($badInteger);
    }
}
