<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\ActivityBundle\Tests\Entity;

use Chill\ActivityBundle\Entity\Activity;
use Chill\PersonBundle\AccompanyingPeriod\SocialIssueConsistency\AccompanyingPeriodSocialIssueConsistencyEntityListener;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Doctrine\ORM\Event\LifecycleEventArgs;
use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;

/**
 * @internal
 *
 * @coversNothing
 */
final class ActivityTest extends TestCase
{
    use ProphecyTrait;

    public function testHierarchySocialActions(): void
    {
        $parent = new SocialAction();
        $child = new SocialAction();

        $parent->addChild($child);
        $grandChild = new SocialAction();
        $child->addChild($grandChild);

        $activity = new Activity();

        $activity->addSocialAction($parent);

        $this->assertCount(1, $activity->getSocialActions());
        $this->assertContains($parent, $activity->getSocialActions());

        $activity->addSocialAction($grandChild);

        $this->assertCount(1, $activity->getSocialActions());
        $this->assertContains($grandChild, $activity->getSocialActions());
        $this->assertNotContains($parent, $activity->getSocialActions());

        $activity->addSocialAction($child);

        $this->assertCount(1, $activity->getSocialActions());
        $this->assertContains($grandChild, $activity->getSocialActions());
        $this->assertNotContains($parent, $activity->getSocialActions());
        $this->assertNotContains($child, $activity->getSocialActions());

        $activity->addSocialAction($another = new SocialAction());

        $this->assertCount(2, $activity->getSocialActions());
        $this->assertContains($grandChild, $activity->getSocialActions());
        $this->assertContains($another, $activity->getSocialActions());
        $this->assertNotContains($parent, $activity->getSocialActions());
        $this->assertNotContains($child, $activity->getSocialActions());
    }

    public function testHierarchySocialIssues(): void
    {
        $listener = new AccompanyingPeriodSocialIssueConsistencyEntityListener();
        $event = $this->prophesize(LifecycleEventArgs::class)->reveal();

        $parent = new SocialIssue();
        $child = new SocialIssue();

        $parent->addChild($child);
        $grandChild = new SocialIssue();
        $child->addChild($grandChild);

        $activity = new Activity();
        $activity->setAccompanyingPeriod(new AccompanyingPeriod());

        $activity->addSocialIssue($parent);
        $listener->preUpdate($activity, $event);

        $this->assertCount(1, $activity->getSocialIssues());
        $this->assertContains($parent, $activity->getSocialIssues());

        $activity->addSocialIssue($grandChild);
        $listener->preUpdate($activity, $event);

        $this->assertCount(1, $activity->getSocialIssues());
        $this->assertContains($grandChild, $activity->getSocialIssues());
        $this->assertNotContains($parent, $activity->getSocialIssues());

        $activity->addSocialIssue($child);
        $listener->preUpdate($activity, $event);

        $this->assertCount(1, $activity->getSocialIssues());
        $this->assertContains($grandChild, $activity->getSocialIssues());
        $this->assertNotContains($parent, $activity->getSocialIssues());
        $this->assertNotContains($child, $activity->getSocialIssues());

        $activity->addSocialIssue($another = new SocialIssue());
        $listener->preUpdate($activity, $event);

        $this->assertCount(2, $activity->getSocialIssues());
        $this->assertContains($grandChild, $activity->getSocialIssues());
        $this->assertContains($another, $activity->getSocialIssues());
        $this->assertNotContains($parent, $activity->getSocialIssues());
        $this->assertNotContains($child, $activity->getSocialIssues());
    }
}
