<?php

namespace Fifa\ConnectId\Sdk\Util\PersonLocalXmlSerializer;

use Fifa\ConnectId\Sdk\Exception\XmlDeserializationException;
use Fifa\ConnectId\Sdk\Exception\XmlSerializationException;
use Fifa\ConnectId\Sdk\Model\DataStandard\PersonLocal;
use Fifa\ConnectId\Sdk\Util\Serialization\Configurations\CommonXmlSerializerConfiguration;
use Fifa\ConnectId\Sdk\Util\Serialization\Configurations\PersonLocalXmlSerializerConfiguration;
use Fifa\ConnectId\Sdk\Util\Serialization\ValidatingXmlSerializer;
use Fifa\ConnectId\Sdk\Util\Serialization\ValidatingXmlSerializerBase;
use Fifa\ConnectId\Sdk\Util\XmlDeserializer\XmlDeserializer;
use XML_Serializer;

/**
 * Class PersonLocalXmlSerializer
 * @package Fifa\ConnectId\Sdk\Util\PersonLocalXmlSerializer
 */
class PersonLocalXmlSerializer implements PersonLocalXmlSerializerInterface
{
    /**
     * @var ValidatingXmlSerializerBase
     */
    private $internalSerializer;

    /**
     * PersonLocalXmlSerializer constructor.
     */
    public function __construct()
    {
        $xmlDeserializer = new XmlDeserializer(PersonLocal::class,
            PersonLocalXmlSerializerConfiguration::getMappings(),
            CommonXmlSerializerConfiguration::getCustomConstructors()
        );

        $xmlSerializer = new XML_Serializer();
        $xmlSerializer->setOptions(CommonXmlSerializerConfiguration::buildOptions('PersonLocal',
            [
                XML_SERIALIZER_OPTION_SCALAR_AS_ATTRIBUTES => PersonLocalXmlSerializerConfiguration::getScalarAsAttributes(),
                XML_SERIALIZER_OPTION_TAGMAP => PersonLocalXmlSerializerConfiguration::getTagmap()
            ])
        );

        $this->internalSerializer = new ValidatingXmlSerializer($xmlSerializer, $xmlDeserializer, function ($item) {
            $this->nullifyUnsetArrays($item);
        });
    }

    /**
     * @param PersonLocal $personLocal
     * @internal - Internal use only
     */
    function nullifyUnsetArrays(PersonLocal $personLocal)
    {
        if (is_array($personLocal->PlayerRegistration) && empty($personLocal->PlayerRegistration)) {
            $personLocal->PlayerRegistration = null;
        }
        if (is_array($personLocal->MatchOfficialRegistration) && empty($personLocal->MatchOfficialRegistration)) {
            $personLocal->MatchOfficialRegistration = null;
        }
        if (is_array($personLocal->TeamOfficialRegistration) && empty($personLocal->TeamOfficialRegistration)) {
            $personLocal->TeamOfficialRegistration = null;
        }
        if (is_array($personLocal->OrganisationOfficialRegistration) && empty($personLocal->OrganisationOfficialRegistration)) {
            $personLocal->OrganisationOfficialRegistration = null;
        }
    }

    /**
     * @param PersonLocal $personLocal
     * @return string
     * @throws XmlSerializationException
     */
    public function serialize(PersonLocal $personLocal): string
    {
        return $this->internalSerializer->serialize($personLocal);
    }

    /**
     * @inheritDoc
     * @throws XmlDeserializationException
     */
    public function deserialize(string $xml) : PersonLocal
    {
        /** @var $person PersonLocal */
        $person = $this->internalSerializer->deserialize($xml);

        return $person;
    }
}