<?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\MultipleWs\Version2\UserACL\Validate;

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 Symfony\Component\HttpFoundation\Request;
use Sso\RestBundle\Worker\IdpWs\ServiceUser\GetValidateUserIdentifier\Handler as ValidateIdentifierHandler;
use Sso\RestBundle\ModelRest\Response\IdpWs\ServiceUser\Get\UserIdentifier as GetValidateIdentifier;
use Sso\RestBundle\ModelRest\Response\UserWs\Version2\UserApplication\ShowDetails\Success\Response as ApplicationShowDetailsSuccess;
use Sso\RestBundle\ModelRest\Response\UserWs\Version2\UserApplication\ShowDetails\Error\Response as ApplicationShowDetailsError;
use Sso\RestBundle\Worker\UserWs\Version2\UserApplication\ShowDetails\Handler as ShowDetailsHandler;
use Sso\RestBundle\ModelRest\Response\UserWs\Version2\UserApplication\ShowDetails\Error\UserType as ErrorUserType;
use Sso\RestBundle\ModelRest\Response\MultipleWs\Version1\Object\Scope\Tree\Success\Response as ScopeTreeResponse;

/**
 * Class Handler
 * @package Sso\RestBundle\Worker\MultipleWs\Version2\UserACL\Validate
 */
class Handler
{
    /**
     * @var ApiManager
     */
    private $apiM;

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

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

    /**
     * @var GetValidateIdentifier
     */
    private $getValidatedIdentifier;

    /**
     * @var ShowDetailsHandler
     */
    private $userApplicationDetails;

    /**
     * @var ValidateIdentifierHandler
     */
    private $validateIdentifier;

    /**
     * @var ApplicationShowDetailsSuccess
     */
    private $applicationShowDetailsSuccess;

    /**
     * @var ApplicationShowDetailsError
     */
    private $applicationShowDetailsError;

    /**
     * @var ErrorUserType
     */
    private $errorUserType;

    /**
     *
     * @param ApiManager $apiM
     */
    public function __construct(ApiManager $apiM)
    {
        $this->apiM = $apiM;
        $this->errorApi = $this->apiM->errorManager();
        $this->errors = $this->errorApi->error()->errors();

        $this->validateIdentifier = new ValidateIdentifierHandler($this->apiM);
        $this->userApplicationDetails = new ShowDetailsHandler($this->apiM);

        $this->getValidatedIdentifier = $this->apiM->modelRest()->response()->idpWs()->serviceUser()->validate();
        $this->applicationShowDetailsSuccess = $this->apiM->modelRest()->response()->userWs()->version2()->userApplication()->showDetails()->success()->response();
        $this->applicationShowDetailsError = $this->apiM->modelRest()->response()->userWs()->version2()->userApplication()->showDetails()->error()->response();

        $this->errorUserType = $this->apiM->modelRest()->response()->userWs()->version2()->userApplication()->showDetails()->error()->userType();
    }


    /**
     * @param Request $request
     * @param ScopeTreeResponse $scopeTreeResponse
     * @return RestView|null
     */
    public function init(Request $request, ScopeTreeResponse $scopeTreeResponse)
    {
        $this->apiM->errorManager()->error()->errors()->getErrors()->removeCount();
        $validateIdentifier = $this->validateIdentifier->init($request)->getData();

        $request->query->set('identifier', $request->query->get('username'));
        if ($request->query->has('appName')) {
            $request->query->set('appName', [$request->query->get('appName')]);
        } else {
            //fallback
            $request->query->set('appName', ['SsoAdmin']);
        }

        $userApplicationShowDetails = $this->userApplicationDetails->init($request)->getData();

        if (200 !== $validateIdentifier->getCode()) {
            $view = RestView::create();
            return $view->setData($validateIdentifier)->setStatusCode($validateIdentifier->getCode());
        }

        if (200 === $userApplicationShowDetails->getCode()) {
            return $this->buildSuccessView($userApplicationShowDetails, $validateIdentifier, $scopeTreeResponse);
        }

        return $this->buildErrorView($userApplicationShowDetails, $validateIdentifier);
    }


    /**
     * @param ApplicationShowDetailsSuccess $userApplicationShowDetails
     * @param  GetValidateIdentifier $validateIdentifier
     * @return RestView
     */
    private function buildSuccessView(
        ApplicationShowDetailsSuccess $userApplicationShowDetails,
        GetValidateIdentifier $validateIdentifier,
        ScopeTreeResponse $scopeTreeResponse
    ) {
        $userApplicationShowDetails->getUserType()->setSessionLifeTime($validateIdentifier->getSessionLifeTime()
            ->format('Y-m-d\TH:i:sP'))->setUserIdentifier($validateIdentifier->getUserIdentifier());

        $aclResponse = $this->apiM->modelRest()->response()->MultipleWs()->version2()->validate()->userACL()->response();
        $aclResponse->setTrackId($userApplicationShowDetails->getTrackId());
        $aclResponse->setCode($userApplicationShowDetails->getCode());
        $aclResponse->setDate($userApplicationShowDetails->getDate());
        $aclResponse->setScriptTimeSec($userApplicationShowDetails->getScriptTimeSec());
        $aclResponse->setStatus($userApplicationShowDetails->getStatus());
        $aclResponse->setUserType($userApplicationShowDetails->getUserType());
        foreach ($userApplicationShowDetails->getApplicationTypes() as $applicationType) {
            $aclResponse->addApplicationType($applicationType);
        }
        foreach ($scopeTreeResponse->getObjects() as $scopeObject) {
            $aclResponse->addObject($scopeObject);
        }

        $view = RestView::create();
        return $view->setData($aclResponse)->setStatusCode(200);
    }

    /**
     * @param ApplicationShowDetailsError $userApplicationShowDetails
     * @param GetValidateIdentifier $validateIdentifier
     * @return RestView
     */
    private function buildErrorView(
        ApplicationShowDetailsError $userApplicationShowDetails,
        GetValidateIdentifier $validateIdentifier
    ) {
        /**
         *  Change code because iDp returned right one (200)
         */
        $userApplicationShowDetails->setCode($validateIdentifier->getCode());
        $this->errorUserType->setSessionLifeTime($validateIdentifier->getSessionLifeTime()
            ->format('Y-m-d\TH:i:sP'));
        $this->errorUserType->setUserIdentifier($validateIdentifier->getUserIdentifier());
        $userApplicationShowDetails->setUserType($this->errorUserType);
        $view = RestView::create();
        return $view->setData($userApplicationShowDetails)->setStatusCode($validateIdentifier->getCode());
    }
}
