<?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\WebserviceBundle\Api\Controller;

use Sso\WebserviceBundle\Api\Error\Type\External as ExternalError;
use Sso\WebserviceBundle\Api\Response\Builder as XmlResponse;

/**
 * Class UserServiceController
 * @package Sso\WebserviceBundle\Api\Controller
 */
class UserServiceController extends AbstractController
{
    /**
     * @return array
     */
    protected function _getActions()
    {
        return array(
            'PasswordRequest',
            'PasswordConfirm',
            'ActivateRequest',
            'ActivateConfirm',
        );
    }

    /**
     * Request token to change password
     *
     * @param \SimpleXMLElement $xmlRequest
     * @param XmlResponse $xmlResponse
     */
    protected function passwordRequest(\SimpleXMLElement $xmlRequest, XmlResponse $xmlResponse)
    {
        $requestModel = $this->modelFactory->request()->userService()->passwordRequest($xmlRequest);
        $userModel = $requestModel->getUserModel();

        if (!$requestModel->hasErrors() && !($user = $this->dbM->user()->getUserByUser($userModel))) {
            $requestModel->addError(new ExternalError('us011', 'UserNotFound'));
        }
        if (!$requestModel->hasErrors()) {
            $user->setValidator($this->apiM->validator());
            $user->generatePasswordRequestToken();
            $requestModel->setUserModel($user);
            if (!$this->dbM->user()->saveUser($user)) {
                $requestModel->addErrors($user->errors()->getErrors());
            }
        }
        $this->modelFactory->response($xmlResponse)->userService()->passwordRequest($requestModel);
    }

    /**
     * Confirm new password
     *
     * @param \SimpleXMLElement $xmlRequest
     * @param XmlResponse $xmlResponse
     */
    protected function passwordConfirm(\SimpleXMLElement $xmlRequest, XmlResponse $xmlResponse)
    {
        $requestModel = $this->modelFactory->request()->userService()->passwordConfirm($xmlRequest);
        $userModel = $requestModel->getUserModel();
        $userUpdateModel = $requestModel->getUserUpdateModel();

        if (!$requestModel->hasErrors() && !($user = $this->dbM->user()->getUserByEmailAndPasswordToken($userUpdateModel->getEmail(),
                $userUpdateModel->getPasswordToken()))
        ) {
            $requestModel->addError(new ExternalError('us021', 'UserTokenNotFound'));
        }
        if (!$requestModel->hasErrors() && $user->hasPasswordTokenExpired()) {
            $requestModel->addError(new ExternalError('us022', 'UserTokenExpired'));
        }
        if (!$requestModel->hasErrors()) {
            $user->merge($userModel);
            $user->setValidator($this->apiM->validator());
            $user->clearPasswordRequestToken();
            if (!$this->dbM->user()->saveUser($user)) {
                $requestModel->addErrors($user->errors()->getErrors());
            }
        }

        // save to password history
        if (!$requestModel->hasErrors()) {
            $this->apiM->passwordHistory()->addPassword(
                $user->getGuid(),
                $user->getPassword(),
                $user->getPasswordEncryptType()
            );
        }

        $this->modelFactory->response($xmlResponse)->userService()->passwordConfirm($requestModel);
    }

    /**
     * Request token to activate user
     *
     * @param \SimpleXMLElement $xmlRequest
     * @param XmlResponse $xmlResponse
     */
    protected function activateRequest(\SimpleXMLElement $xmlRequest, XmlResponse $xmlResponse)
    {
        $requestModel = $this->modelFactory->request()->userService()->activateRequest($xmlRequest);
        $userModel = $requestModel->getUserModel();

        if (!$requestModel->hasErrors() && !($user = $this->dbM->user()->getUserByUser($userModel))) {
            $requestModel->addError(new ExternalError('us031', 'UserNotFound'));
        }
        if (!$requestModel->hasErrors() && $user->getActive()) {
            $requestModel->addError(new ExternalError('us032', 'UserIsActive'));
        }
        if (!$requestModel->hasErrors()) {
            $user->generateActivateRequestToken();
            $requestModel->setUserModel($user);
            if (!$this->dbM->user()->saveUser($user)) {
                $requestModel->addErrors($user->errors()->getErrors());
            }
        }
        $this->modelFactory->response($xmlResponse)->userService()->activateRequest($requestModel);
    }

    /**
     * Activate user
     *
     * @param \SimpleXMLElement $xmlRequest
     * @param XmlResponse $xmlResponse
     */
    protected function activateConfirm(\SimpleXMLElement $xmlRequest, XmlResponse $xmlResponse)
    {
        $requestModel = $this->modelFactory->request()->userService()->activateConfirm($xmlRequest);
        $userModel = $requestModel->getUserModel();
        $userUpdateModel = $requestModel->getUserUpdateModel();

        if (!$requestModel->hasErrors() && !($user = $this->dbM->user()->getUserByEmailAndActivateToken($userUpdateModel->getEmail(),
                $userUpdateModel->getActivateToken()))
        ) {
            $requestModel->addError(new ExternalError('us041', 'UserActivateTokenNotFound'));
        }
        if (!$requestModel->hasErrors() && $user->hasActivateTokenExpired()) {
            $requestModel->addError(new ExternalError('us042', 'UserActivateTokenExpired'));
        }
        if (!$requestModel->hasErrors() && $user->getActive()) {
            $requestModel->addError(new ExternalError('us043', 'UserIsActive'));
        }
        if (!$requestModel->hasErrors()) {
            $user->setActive(1);
            if (!$this->dbM->user()->saveUser($user)) {
                $requestModel->addErrors($user->errors()->getErrors());
            }
        }
        $this->modelFactory->response($xmlResponse)->userService()->activateConfirm($requestModel);
    }

}
