<?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\UserWs\Version2\UserApplication\ShowDetails;

use FOS\RestBundle\View\View as RestView;
use Sso\RestBundle\Api\Manager as ApiManager;
use LifeStyle\Tools\RestErrorBundle\Api\Manager as ErrorApi;
use LifeStyle\Tools\RestErrorBundle\Api\Error\Errors\Index as Errors;
use GuzzleHttp\Exception\RequestException;
use LifeStyle\Tools\RestAuthBundle\Security\Authentication\Token\UidentifyToken;
use Symfony\Component\HttpFoundation\Request;
use GuzzleHttp\Client;
use Sso\RestBundle\ModelRest\Request\UserWs\Version2\UserApplication\ShowDetails\Request as RequestModel;
use Sso\RestBundle\ModelRest\Response\UserWs\Version2\UserApplication\ShowDetails\Factory as ResponseModel;
use Sso\RestBundle\Api\Helper\Mapper\Index as Mapper;
use Sso\RestBundle\ModelXml\Response\UserWs\Version2\UserApplication\ShowDetails\Error\Response as XmlError;
use Sso\RestBundle\ModelXml\Response\UserWs\Version2\UserApplication\ShowDetails\Success\Response as XmlSuccess;
use Sso\RestBundle\Worker\UserWs\Version2\UserApplication\ShowDetails\Utils\Index as Utils;
use Sso\RestBundle\Api\ExceptionCollection\MainValidationException;

/**
 * Class Handler
 * @package Sso\RestBundle\Worker\UserWs\Version2\UserApplication\ShowDetails
 */
class Handler
{

    const STATUS = "status";
    const ERROR_EXTERNAL = "external";

    /**
     * @var UidentifyToken
     */
    private $userToken;

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

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

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

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

    /**
     * @var Mapper
     */
    private $mapper;

    /**
     * @var Utils
     */
    private $utils;

    /**
     * @param ApiManager $apiM
     */
    public function __construct(ApiManager $apiM)
    {
        $this->apiM = $apiM;
        $this->errorApi = $this->apiM->errorManager();
        $this->errors = $this->errorApi->error()->errors();
        $this->userToken = $this->apiM->getToken();
        $this->mapper = $this->apiM->helper()->mapper();
        $this->client = $this->apiM->client();
        $this->utils = new Utils($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());
        }

        return $this->sendXmlRequest($requestModelRest);
    }


    /**
     * @param Request $request
     * @return RequestModel $requestModel
     */
    private function validateRestRequest(Request $request)
    {
        $requestModel = $this->apiM->modelRest()->request()->userWs()->version2()->userApplication()->showDetails();

        if ($request->query->has('identifier')) {
            $requestModel->setIdentifier($request->query->get('identifier'));
        }

        if ($request->query->has('appName')) {
            $requestModel->setAppName($request->query->get('appName'));
        }


        $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;
    }

    /**
     * @param RequestModel $requestItem
     * @return RestView
     */
    private function sendXmlRequest(RequestModel $requestItem)
    {

        $requestModel = $this->apiM->modelXml()->request()->userWs()->version2()->userApplication()->showDetails()->request();
        $objectModelXml = $this->apiM->modelXml()->request()->userWs()->version2()->userApplication()->showDetails()->userApplication();
        $objectModelXml->setUserApplicationData($requestItem->getIdentifier(), $requestItem->getAppNames());
        $requestModel->setUserApplication($objectModelXml);

        // add credentials
        $credentialsModelXml = $this->apiM->modelXml()->request()->userWs()->version2()->userApplication()->showDetails()->credentials();
        $credentialsModelXml->setCredentialsData($this->userToken->servicetoken, 'UserApplicationShowDetails',
            $this->userToken->useridentifier, $this->userToken->username, 'en');
        $requestModel->setCredentials($credentialsModelXml);

        try {
            $clientResponse = $this->client->post(
                $this->apiM->configuration()->userWs()->getBaseUrl() . $this->apiM->configuration()->userWs()->getServiceAction(),
                $this->apiM->clientHelper()->options()->getOptions(
                    2,
                    'UserApplication',
                    'ShowDetails',
                    $this->apiM->serializer()->serialize($requestModel, 'xml')
                )
            );

        } catch (RequestException $ex) {
            $errorResponse = $ex->getResponse()->getBody()->getContents();
            $this->apiM->logger()->error($errorResponse);

            return $this->utils->buildItem([static::STATUS => false, 'xml' => $errorResponse]);
        }

        return $this->utils->buildItem([static::STATUS => true, 'xml' => $clientResponse->getBody()->getContents()]);
    }
}
