<?php

namespace Fifa\ConnectId\Sdk;

use Fifa\ConnectId\Sdk\ApiModelValidation\ApiModelValidator;
use Fifa\ConnectId\Sdk\ApiModelValidation\SystemIdValidator;
use Fifa\ConnectId\Sdk\Exception\XmlSerializationException;
use Fifa\ConnectId\Sdk\Model\DataStandard\PersonLocal;
use Fifa\ConnectId\Sdk\Registration\ValidationException;
use Fifa\ConnectId\Sdk\Tms\Validators\PersonLocalValidator;
use Fifa\ConnectId\Sdk\Util\Data\Message\MessageProperties;
use Fifa\ConnectId\Sdk\Util\PersonLocalXmlSerializer\PersonLocalXmlSerializer;
use Fifa\ConnectId\Sdk\Util\SdkVersionHelper;
use Fifa\ConnectServiceBus\Sdk\Exception\AuthenticationException;
use Fifa\ConnectServiceBus\Sdk\Exception\FifaConnectServiceBusSdkException;
use Fifa\ConnectServiceBus\Sdk\Exception\InvalidClientDataException;
use Fifa\ConnectServiceBus\Sdk\Exception\QueueNotFoundException;
use Fifa\ConnectServiceBus\Sdk\Exception\UnauthorizedException;
use Fifa\ConnectServiceBus\Sdk\FifaConnectServiceBusClientInterface;
use Fifa\ConnectServiceBus\Sdk\Message\Message;

class PersonLocalSender
{
    /**
     * @var FifaConnectServiceBusClientInterface
     */
    private $serviceBusClient;

    /**
     * @var PersonLocalXmlSerializer
     */
    private $personLocalXmlSerializer;

    public function __construct(FifaConnectServiceBusClientInterface $serviceBusClient)
    {
        $this->serviceBusClient = $serviceBusClient;
        $this->personLocalXmlSerializer = new PersonLocalXmlSerializer();
    }

    /**
     * Sends person data to the specified recipient.
     *
     * @param PersonLocal $personLocal - Person details using FIFA Data Standard
     * @param string $recipient - System Identifier of the receiver of the data
     * @param string $messageType - the message identifier agreed between the sending and the receiving party
     * @return void
     *
     * @throws XmlSerializationException
     * @throws ValidationException
     * @throws InvalidClientDataException
     * @throws QueueNotFoundException
     * @throws FifaConnectServiceBusSdkException
     * @throws UnauthorizedException
     * @throws AuthenticationException
     */
    public function send(PersonLocal $personLocal, string $recipient, string $messageType) {
        SystemIdValidator::validate($recipient, 'recipient');
        ApiModelValidator::cannotBeNullOrWhitespace($messageType, 'messageType');
        PersonLocalValidator::validate($personLocal);

        $properties = [
            MessageProperties::UNIQUE_FIFA_ID => $personLocal->PersonFIFAId,
            MessageProperties::VERSION => SdkVersionHelper::getSdkVersion()
        ];
        $content = $this->personLocalXmlSerializer->serialize($personLocal);
        $message = new Message($content, $messageType, $properties);

        $this->serviceBusClient->send($recipient, $message);
    }
}