<?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  2018 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 */

namespace Sso\RestBundle\Worker\ObjectWs\Version1\ObjectValue\Add;

use FOS\RestBundle\View\View as RestView;
use Sso\RestBundle\Api\Manager as ApiManager;
use GuzzleHttp\Client;
use LifeStyle\Tools\RestErrorBundle\Api\Manager as ErrorApi;
use LifeStyle\Tools\RestErrorBundle\Api\Error\Errors\Index as Errors;
use Symfony\Component\HttpFoundation\Request;
use Sso\RestBundle\ModelRest\Request\ObjectWs\Version1\ObjectValue\Add\Request as RequestModel;
use Sso\RestBundle\ModelRest\Response\ObjectWs\Version1\ObjectValue\Add\Response as ResponseModel;
use LifeStyle\Tools\RestAuthBundle\Security\Authentication\Token\UidentifyToken;

/**
 * Class Handler
 *
 * @copyright  2016 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 * @package    Sso\RestBundle\Worker\ObjectWs\Version1\ObjectValue\Add
 */
class Handler
{
    /**
     * @var UidentifyToken
     */
    protected $userToken;

    /**
     * @var ApiManager
     */
    protected $apiM;

    /**
     * @var ErrorApi
     */
    protected $errorApi;

    /**
     * @var Errors
     */
    protected $errors;

    /**
     * @var ResponseModel
     */
    protected $restResponseEntity;

    /**
     * @var string
     */
    protected $format;

    /**
     * @var Utils\Factory
     */
    protected $utilsFactory;

    /**
     * @var Client
     */
    private $client;

    /**
     * @param ApiManager $apiM
     */
    public function __construct(ApiManager $apiM)
    {
        $this->apiM = $apiM;
        $this->client = $apiM->client();
        $this->errorApi = $this->apiM->errorManager();
        $this->errors = $this->errorApi->error()->errors();
        $this->format = 'json';
        $this->userToken = $this->apiM->getToken();
        $this->restResponseEntity = $this->apiM->modelRest()->response()->objectWs()->version1()->objectValue()->add()->response();
        $this->utilsFactory = new Utils\Factory($this->apiM);
    }

    /**
     * @param Request $request
     * @return RestView
     */
    public function init(Request $request)
    {
        // first: validate input data
        $requestModelRest = $this->validateRestRequest($request);

        if ($this->errors->hasErrors()) {
            return $this->errorApi->error()->view()->getErrorsView($this->errors->getErrors());
        }

        // second: send data to object ws ObjectValueAdd
        foreach ($requestModelRest->getItem() as $item) {
            $responseItem = $this->utilsFactory->objectValueAdd($this->client)->send($item);

            //now add the current item to the response
            $this->restResponseEntity->addItem($responseItem);
        }

        $view = RestView::create();
        $view->setData($this->restResponseEntity)->setStatusCode(200);

        return $view;
    }

    /**
     * @param Request $request
     * @return RequestModel
     */
    private function validateRestRequest(Request $request)
    {
        // check content
        $requestContent = $request->getContent();
        if (empty($requestContent)) {
            $this->errors->addError(204, 'No Content found in your request', 'external')->setCode(204);
            return;
        }

        $this->format = preg_match('/\.xml/i', $request->getUri()) ? 'xml' : 'json';

        //no validate the content
        if ($this->format == "xml") {
            $errors = $this->apiM->helper()->string()->validateXML($requestContent);
        } else {
            $errors = $this->apiM->helper()->string()->validateJson($requestContent);
        }
        // collect errors
        foreach ($errors as $error) {
            $this->errors->addError(400, $error, 'external', 'InvalidRequest')->setCode(400);
            return;
        }

        //now build request model
        $requestModel = $this->apiM->serializer()->deserialize($requestContent,
            'Sso\RestBundle\ModelRest\Request\ObjectWs\Version1\ObjectValue\Add\Request', $this->format);

        $validationErrors = $this->apiM->validator()->validate($requestModel);

        if (count($validationErrors) > 0) {
            foreach ($validationErrors as $error) {
                $message = $error->getPropertyPath() . ": " . $error->getMessage();
                $this->errors->addError(400, $message, 'external')->setCode(400);
            }
        }
        return $requestModel;
    }
}
