<?php

/**
 * Lifestyle Webconsulting GmbH
 *
 * LICENSE: This Software is the property of Lifestyle Webconsulting GmbH (Aschaffenburg, Germany)
 * and is private by copyright law - it is NOT Freeware.
 *
 * Any unauthorized use of this software without a valid license
 * is a violation of the license agreement and will be prosecuted by
 * civil and criminal law.
 *
 * @copyright  2019 Lifestyle Webconsulting GmbH
 * @link       https://www.life-style.de
 */

namespace Sso\WebserviceBundle\Services\UserGroup\Update\Response\Version2;

use Sso\WebserviceBundle\ErrorHandler\ErrorHandlerInterface;
use Sso\WebserviceBundle\Services\UserGroup\Update\ResponseBuilderInterface;
use Sso\WebserviceBundle\Services\UserGroup\Update\ResponseData\UserGroup;
use JMS\Serializer\SerializerInterface;
use Sso\WebserviceBundle\Services\UserGroup\Update\ResponseData\UserGroup as UserGroupData;

/**
 * Class ResponseBuilder
 *
 * @copyright  2019 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 * @package Sso\WebserviceBundle\Services\UserGroup\Update\Response\Version2
 */
final class ResponseBuilder implements ResponseBuilderInterface
{
    /**
     * @var SerializerInterface
     */
    private $serializer;

    /**
     * @var Factory
     */
    private $factory;

    /**
     * @var ErrorHandlerInterface
     */
    private $errorHandler;

    /**
     * @var UserGroupData
     */
    private $responseData;

    /**
     * @var array
     */
    private $userGroupTypeMapping = array(
        'getId' => 'id',
        'getName' => 'name',
        'getDescription' => 'description',
        'getUpdatedAt' => 'updatedAt',
        'getCreatedAt' => 'createdAt',
    );

    /**
     * ResponseBuilder constructor.
     * @param SerializerInterface $serializer
     * @param Factory $factory
     * @param ErrorHandlerInterface $errorHandler
     */
    public function __construct(SerializerInterface $serializer, Factory $factory, ErrorHandlerInterface $errorHandler)
    {
        $this->serializer = $serializer;
        $this->factory = $factory;
        $this->errorHandler = $errorHandler;
    }

    /**
     * @param UserGroupData $userGroup
     */
    public function setResponse(UserGroup $userGroup)
    {
        $this->responseData = $userGroup;
    }

    /**
     * @return boolean
     */
    public function hasErrors()
    {
        return $this->errorHandler->hasErrors();
    }

    /**
     * @param string $format xml|json
     * @return string Response body
     */
    public function build($format)
    {
        $response = $this->errorHandler->hasErrors() ? $this->getErrorResponse() : $this->getSuccessResponse();
        return $this->serializer->serialize($response, $format);
    }

    /**
     * @return Response
     */
    private function getErrorResponse()
    {
        $response = $this->factory->response();
        $response->setErrors($this->errorHandler->getResponseObject());
        $response->setTrackid(null);
        $response->setDate(null);

        return $response;
    }

    /**
     * @return Response
     */
    private function getSuccessResponse()
    {
        $userGroupType = $this->factory->userGroupType();
        $userGroupType->setFromArray($this->mapUserGroupType($this->responseData));

        $update = $this->factory->update();
        $update->setUserGroupType($userGroupType);
        $update->setStatus('Success');

        $userGroup = $this->factory->userGroup();

        $userGroup->addUpdate($update);

        $response = $this->factory->response();
        $response->setCode(200);
        $response->setScriptTimeSec($this->factory->scriptTimeSeconds());
        $response->setUserGroup($userGroup);

        return $response;
    }

    /**
     * @param UserGroupData $userGroup
     * @return array
     */
    private function mapUserGroupType(UserGroupData $userGroup)
    {
        $userGroupType = array();
        foreach ($this->userGroupTypeMapping as $getter => $attributeName) {
            $userGroupType[$attributeName] = $userGroup->$getter();
        }
        return $userGroupType;
    }
}
