<?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\ApplicationAttribute\Add\Response\Version2;

use JMS\Serializer\SerializerInterface;
use Sso\WebserviceBundle\Api\ApiManagerInterface;
use Sso\WebserviceBundle\ErrorHandler\ErrorHandlerInterface;
use Sso\WebserviceBundle\Services\ApplicationAttribute\Add\ResponseBuilderInterface;
use Sso\WebserviceBundle\Services\ApplicationAttribute\Add\ResponseData\ApplicationAttributeData;
use Sso\WebserviceBundle\Services\ResponseBuilderInterface as GlobalResponseBuilderInterface;

/**
 * Class ResponseBuilder
 *
 * @copyright  2019 Lifestyle Webconsulting GmbH
 * @link       https://www.life-style.de
 * @package Sso\WebserviceBundle\Services\ApplicationAttribute\Add\Response\Version2
 */
class ResponseBuilder implements ResponseBuilderInterface, GlobalResponseBuilderInterface
{
    /**
     * @var ApiManagerInterface
     */
    private $apiManager;

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

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

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

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

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

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

    /**
     * @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->resetTrackid();
        $response->resetDate();

        return $response;
    }

    /**
     * @return Response
     */
    private function getSuccessResponse()
    {
        $attributeOptions = [];
        foreach ($this->responseData->getAttributeOptions() ?? [] as $label => $value) {
            $attributeOption = $this->factory->attributeOption();
            $attributeOption->setLabel($label);
            $attributeOption->setValue($value);
            $attributeOptions[] = $attributeOption;
        }

        $attributeType = $this->factory->attributeType();
        $attributeType->setName($this->responseData->getAttributeName());
        $attributeType->setType($this->responseData->getAttributeType());
        $attributeType->setDisplayType($this->responseData->getAttributeDisplayType());
        $attributeType->setAttributeOptions(0 < count($attributeOptions) ? $attributeOptions : null);

        $add = $this->factory->add();
        $add->setStatus('Success');
        $add->setAttributeType($attributeType);

        $applicationAttribute = $this->factory->applicationAttribute();
        $applicationAttribute->setAdd($add);

        $response = $this->factory->response();
        $response->setCode(200);
        $response->setScriptTimeSec($this->apiManager->scriptTimeSeconds());
        $response->setApplicationAttribute($applicationAttribute);

        return $response;
    }
}
