<?PHP
/**
 * Tests for plausi for legal status.
 *
 * @author Joshua Ramon Enslin <joshua@museum-digital.de>
 */
declare(strict_types = 1);

use PHPUnit\Framework\TestCase;

require_once __DIR__ . '/../src/Checks/PlausiForLegalStatus/MDPlausiForLegalStatus.php';
require_once __DIR__ . '/../src/Checks/PlausiForLegalStatus/MDPlausiLegalCheckResultType.php';
require_once __DIR__ . '/../src/Checks/PlausiForLegalStatus/MDPlausiLegalCheckReason.php';
require_once __DIR__ . '/../src/Checks/Puqi/MDPuqi.php';
require_once __DIR__ . '/../src/Checks/Plausi/MDEventCategory.php';
require_once __DIR__ . '/../src/Checks/Plausi/MDPlausiEvent.php';
// require_once __DIR__ . '/../../MDTlLoader/src/MDTlLoader.php';
require_once __DIR__ . '/../../importer/dependencies/MDAllowedValueSets/src/MDRequirementsSet.php';
require_once __DIR__ . '/../../importer/dependencies/MDAllowedValueSets/src/MDValueSet.php';
require_once __DIR__ . '/../../importer/dependencies/MDAllowedValueSets/src/MDEventsSet.php';
require_once __DIR__ . '/../../importer/dependencies/MDAllowedValueSets/src/enums/MDCopyrightCollective.php';

/**
 * Tests for PlausiForLegalStatus.
 */
final class MDPlausiForLegalStatusTest extends TestCase {
    /**
     * Ensures that no warning is present if no information has been provided.
     *
     * @return void
     */
    public function testNoWarningForObjectWithNoInfo():void {

        $plausiEvent = new MDPlausiEvent(1,
            "",
            "",
            "",
            "",
            "",
            "");

        $plausiLegal = new MDPlausiForLegalStatus([$plausiEvent], [['name' => 'test.jpg', 'license' => 'RR-F']]);
        $warningStatus = $plausiLegal->evaluateSimple();

        self::assertFalse($warningStatus['has_warning']);
        self::assertEmpty($warningStatus['msgs']);

    }

    /**
     * Ensures that no warning is present if no information has been provided.
     *
     * @return void
     */
    public function testNoWarningForObjectWithActorsDeceased95YearsAgo():void {

        $plausiEvent = new MDPlausiEvent(1,
            "",
            "",
            "",
            "Somebody",
            date("Y", strtotime("-95 years")),
            date("Y", strtotime("-95 years")));

        $plausiLegal = new MDPlausiForLegalStatus([$plausiEvent], [['name' => 'test.jpg', 'license' => 'RR-F']]);
        $warningStatus = $plausiLegal->evaluateSimple();

        self::assertFalse($warningStatus['has_warning']);
        self::assertEmpty($warningStatus['msgs']);

    }

    /**
     * Ensures that a warning is returned, if the object's representations are published under
     * restrictive licenses Checks the integration / evaluation function.
     *
     * @return void
     */
    public function testPublicDomainObjectExpectsPd():void {

        $plausiEvent = new MDPlausiEvent(1,
            "1899",
            "1899",
            "1899",
            "Helmut Meyer",
            "1859",
            "1900");

        $plausiLegal = new MDPlausiForLegalStatus([$plausiEvent], [['name' => 'test.jpg', 'license' => 'RR-F']]);
        $warningStatus = $plausiLegal->evaluateSimple();

        self::assertTrue($warningStatus['has_warning']);
        self::assertNotEmpty($warningStatus['msgs']);
        self::assertEquals(MDPlausiLegalCheckResultType::expect_public_domain, $warningStatus['msgs'][0]['type']);

    }

    /**
     * Ensures that a warning is returned, if the object's representations are published under
     * restrictive licenses Checks the integration / evaluation function.
     *
     * @return void
     */
    public function testPublicDomainObjectExpectsPdWithNonProductionSecondEvent():void {

        $plausiEvent = new MDPlausiEvent(1,
            "1899",
            "1899",
            "1899",
            "Helmut Meyer23",
            "1859",
            "1900");

        $plausiEvent2 = new MDPlausiEvent(6,
            "1999",
            "1999",
            "1999",
            "Somebody else",
            "1999",
            "2000");

        $plausiLegal = new MDPlausiForLegalStatus([$plausiEvent, $plausiEvent2], [['name' => 'test23.jpg', 'license' => 'RR-F']]);
        $warningStatus = $plausiLegal->evaluateSimple();

        self::assertTrue($warningStatus['has_warning']);
        self::assertNotEmpty($warningStatus['msgs']);
        self::assertEquals(MDPlausiLegalCheckResultType::expect_public_domain, $warningStatus['msgs'][0]['type']);

    }

    /**
     * Ensures that a warning is returned, if the object's representations are published under
     * restrictive licenses Checks the integration / evaluation function.
     *
     * @return void
     */
    public function testPublicDomainObjectExpectsPdForActorsWithNoDeathDateBornInMedievalTimes():void {

        $plausiEvent = new MDPlausiEvent(1,
            "",
            "",
            "",
            "Helmut Meyer23",
            "1400",
            "");

        $plausiLegal = new MDPlausiForLegalStatus([$plausiEvent], [['name' => 'test23.jpg', 'license' => 'RR-F']]);
        $warningStatus = $plausiLegal->evaluateSimple();

        self::assertTrue($warningStatus['has_warning']);
        self::assertNotEmpty($warningStatus['msgs']);
        self::assertEquals(MDPlausiLegalCheckResultType::expect_public_domain, $warningStatus['msgs'][0]['type']);

    }

    /**
     * Ensures that a warning is returned if the author / creator died only in the current year.
     *
     * @return void
     */
    public function testCurrentCreatorAsksForRestrictedLicense():void {

        $plausiEvent = new MDPlausiEvent(1,
            date("Y"),
            date("Y"),
            date("Y"),
            "Helmut Meyer",
            strval((int)date("Y") - 20),
            date("Y"));

        $plausiLegal = new MDPlausiForLegalStatus([$plausiEvent], [['name' => 'test.jpg', 'license' => 'Public Domain Mark']]);
        $warningStatus = $plausiLegal->evaluateSimple();

        self::assertTrue($warningStatus['has_warning']);
        self::assertNotEmpty($warningStatus['msgs']);
        self::assertEquals(MDPlausiLegalCheckResultType::expect_restricted_legal_status, $warningStatus['msgs'][0]['type']);

    }

    /**
     * Ensures that a warning is returned if the author / creator died only in the current year.
     *
     * @return void
     */
    public function testCreatorBornWithinLast100YearsAsksForRestrictedLicense():void {

        $plausiEvent = new MDPlausiEvent(1,
            "",
            "",
            "",
            "Helmut Meyer",
            "1922",
            "");

        $plausiLegal = new MDPlausiForLegalStatus([$plausiEvent], [['name' => 'test.jpg', 'license' => 'Public Domain Mark']]);
        $warningStatus = $plausiLegal->evaluateSimple();

        self::assertTrue($warningStatus['has_warning']);
        self::assertNotEmpty($warningStatus['msgs']);
        self::assertEquals(MDPlausiLegalCheckResultType::expect_restricted_legal_status, $warningStatus['msgs'][0]['type']);

    }

    /**
     * Ensures that a warning is returned if the creator is still alive.
     *
     * @return void
     */
    public function testCreatorsWhoAreStillAliveAsksForRestrictedLicense():void {

        $plausiEvent = new MDPlausiEvent(1,
            date("Y"),
            date("Y"),
            date("Y"),
            "Helmut Meyer",
            strval((int)date("Y") - 20),
            "");

        $plausiLegal = new MDPlausiForLegalStatus([$plausiEvent], [['name' => 'test.jpg', 'license' => 'Public Domain Mark']]);
        $warningStatus = $plausiLegal->evaluateSimple();

        self::assertTrue($warningStatus['has_warning'], var_export($plausiLegal, true));
        self::assertNotEmpty($warningStatus['msgs']);
        self::assertEquals(MDPlausiLegalCheckResultType::expect_restricted_legal_status, $warningStatus['msgs'][0]['type']);

    }

    /**
     * Ensures that a warning is returned if the creator is represented by a copyright collective.
     *
     * @return void
     */
    public function testCreatorsInCopyrightCollectiveAsksForRestrictedLicense():void {

        $plausiEvent = new MDPlausiEvent(1,
            date("Y"),
            date("Y"),
            date("Y"),
            "Helmut Meyer",
            strval((int)date("Y") - 20),
            "");

        $plausiLegal = new MDPlausiForLegalStatus([$plausiEvent], [['name' => 'test.jpg', 'license' => 'Public Domain Mark']]);
        $plausiLegal->setCreatorsRepresentedByCopyrightCollective(["Helmut Meyer" => MDCopyrightCollective::vg_bildkunst]);

        $warningStatus = $plausiLegal->evaluateSimple();

        self::assertTrue($warningStatus['has_warning']);
        self::assertNotEmpty($warningStatus['msgs']);
        self::assertEquals(MDPlausiLegalCheckResultType::expect_restricted_legal_status, $warningStatus['msgs'][0]['type']);

        self::assertArrayHasKey('additional', $warningStatus['msgs'][0]);
        // For phpstan
        if (empty($warningStatus['msgs'][0]['additional'])) {
            throw new Exception("Output array should have key 'additional'");
        }
        self::assertEquals(MDCopyrightCollective::vg_bildkunst, $warningStatus['msgs'][0]['additional']['representation']);

    }
}