<?php

namespace Fifa\ConnectId\Sdk\MessageHandlers;

use Fifa\ConnectId\Sdk\Exception\XmlDeserializationException;
use Fifa\ConnectId\Sdk\Registration\ValidationException;
use Fifa\ConnectId\Sdk\Util\Builder\Error\CompositeErrorBuilder;
use Fifa\ConnectId\Sdk\Util\PersonLocalXmlSerializer\PersonLocalXmlSerializer;
use Fifa\ConnectId\Sdk\Util\PersonLocalXmlSerializer\PersonLocalXmlSerializerInterface;
use Fifa\ConnectId\Sdk\Util\StringUtils;
use Fifa\ConnectServiceBus\Sdk\Message\Message;

class PersonLocalMessageHandler implements MessageHandlerInterface
{
    /**
     * @var PersonLocalReceivedHandlerInterface
     */
    private $handler;

    /**
     * @var string
     */
    private $handledMessageType;

    /**
     * @var PersonLocalXmlSerializerInterface
     */
    private $serializer;

    public function __construct(PersonLocalReceivedHandlerInterface $handler, string $handledMessageType)
    {
        $this->handler = $handler;
        $this->handledMessageType = $handledMessageType;
        $this->serializer = new PersonLocalXmlSerializer();
    }

    public function canHandle(?string $messageType): bool
    {
        return $messageType == $this->handledMessageType;
    }

    /**
     * @throws ValidationException
     * @throws XmlDeserializationException
     */
    public function handle(?string $messageType, Message $message)
    {
        $sender = $message->getSender();
        $xmlData = $message->getContent();

        $errorBuilder = new CompositeErrorBuilder();
        $errors = $errorBuilder
            ->addMessageForCase(StringUtils::isNullOrEmpty($sender), 'Invalid PersonLocal message received - there was no sender specified.')
            ->addMessageForCase(StringUtils::isNullOrEmpty($xmlData), 'Invalid PersonLocal message received - there was no content.')
            ->build();

        if (!is_null($errors)) {
            throw new ValidationException($errors);
        }

        $personLocal = $this->serializer->deserialize($xmlData);
        $this->handler->handle($personLocal, $sender);
    }

    /**
     * String representation of the object
     */
    public function __toString()
    {
        return MessageHandlersUtil::FullNameWithMessageType($this, $this->handledMessageType);
    }
}