<?php

namespace App\Message;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;

final class LinkCheckedMessage
{
    /**
     * @var int
     */
    private $linkId;
    /**
     * @var int
     * @Assert\EqualTo(200)
     */
    private $statusCode;
    /**
     * @var float
     * @Assert\LessThanOrEqual(5.0)
     */
    private $responseTime;
    /**
     * @var bool
     * @Assert\IsTrue()
     */
    private $anchorHref;
    /**
     * @var string|null
     */
    private $anchorText;
    /**
     * @var bool|null
     * @Assert\IsFalse()
     */
    private $relNoFollow;
    /**
     * @var int
     */
    private $pageAuthority;
    /**
     * @var array
     */
    private $output;
    /**
     * @var \DateTime
     */
    private $timestamp;
    /**
     * @var string|null
     */
    private $expectedAnchorText;

    public function __construct(
        int $linkId,
        int $statusCode,
        float $responseTime,
        bool $href,
        ?string $expectedAnchorText,
        ?string $anchorText,
        ?bool $relNoFollow,
        int $pageAuthority,
        array $output,
        \DateTime $timestamp
    ) {
        $this->statusCode = $statusCode;
        $this->responseTime = $responseTime;
        $this->anchorHref = $href;
        $this->anchorText = $anchorText;
        $this->relNoFollow = $relNoFollow;
        $this->output = $output;
        $this->linkId = $linkId;
        $this->pageAuthority = $pageAuthority;
        $this->timestamp = $timestamp;
        $this->expectedAnchorText = $expectedAnchorText;
    }

    /**
     * @return int
     */
    public function getLinkId(): int
    {
        return $this->linkId;
    }

    /**
     * @return int
     */
    public function getStatusCode(): int
    {
        return $this->statusCode;
    }

    /**
     * @return float
     */
    public function getResponseTime(): float
    {
        return $this->responseTime;
    }

    /**
     * @return bool
     */
    public function hasHref(): bool
    {
        return $this->anchorHref;
    }

    /**
     * @return string|null
     */
    public function getAnchorText(): ?string
    {
        return $this->anchorText;
    }

    /**
     * @return bool
     */
    public function hasRelNoFollow(): ?bool
    {
        return $this->relNoFollow;
    }

    /**
     * @return int
     */
    public function getPageAuthority(): int
    {
        return $this->pageAuthority;
    }

    /**
     * @return array
     */
    public function getOutput(): array
    {
        return $this->output;
    }

    /**
     * @return \DateTime
     */
    public function getTimestamp(): \DateTime
    {
        return $this->timestamp;
    }

    /**
     * @Assert\Callback()
     */
    public function validateAnchorText(ExecutionContextInterface $context)
    {
        if ($this->expectedAnchorText) {
            $constraint = new Assert\EqualTo((['value' => $this->expectedAnchorText]));
            $context
                ->getValidator()
                ->inContext($context)
                ->atPath('anchorText')
                ->validate($this->anchorText, $constraint, [Constraint::DEFAULT_GROUP]);
        }
    }
}
