<?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\PasswordPolicy\History;

use Sso\WebserviceBundle\Database\Manager as DatabaseManager;
use Sso\WebserviceBundle\Api\PasswordPolicy\Policy\Service as PolicyService;
use Sso\WebserviceBundle\PasswordCrypt\PasswordCryptRepositoryInterface;

/**
 * Class Handler
 * @package Sso\WebserviceBundle\Api\PasswordPolicy\History
 */
class Service
{
    /**
     * @var DatabaseManager
     */
    private $dbManager;

    /**
     * @var PolicyService
     */
    private $policyService;

    /**
     * @var integer
     */
    private $historySize;

    /**
     * @var PasswordCryptRepositoryInterface
     */
    private $passwordCryptRepository;

    /**
     * Service constructor.
     * @param DatabaseManager $dbManager
     * @param PolicyService $policyService
     * @param int $historySize
     * @param PasswordCryptRepositoryInterface $passwordCryptRepository
     */
    public function __construct(
        DatabaseManager $dbManager,
        PolicyService $policyService,
        int $historySize,
        PasswordCryptRepositoryInterface $passwordCryptRepository
    ) {
        $this->dbManager = $dbManager;
        $this->policyService = $policyService;
        $this->historySize = $historySize;
        $this->passwordCryptRepository = $passwordCryptRepository;
    }

    /**
     * @param string $userGuid
     * @param string $password
     * @param string $passwordEncryptType
     */
    public function addPassword($userGuid, $password, string $passwordEncryptType)
    {
        $newPassword = $this->dbManager->webservice()->passwordHistory()->newPassword();
        $newPassword->setUserGuid($userGuid);
        $newPassword->setPassword($password);
        $newPassword->setPasswordEncryptType($passwordEncryptType);
        $newPassword->setAddedAt(new \DateTime);

        $this->dbManager->webservice()->passwordHistory()->savePassword($newPassword);

        $this->cleanUp($userGuid);
    }

    /**
     * @param string $userGuid
     * @param string $password
     * @param int $checkSize
     * @return bool
     */
    public function checkHistory($userGuid, $password, $checkSize)
    {
        if ($checkSize <= 0) {
            return false;
        }

        $passwords = $this->dbManager->webservice()->passwordHistory()->getPasswords($userGuid);

        foreach (array_slice($passwords, 0, $checkSize) as $passwordEntity) {
            $passwordCrypt = $this->passwordCryptRepository->getByEncryptType($passwordEntity->getPasswordEncryptType());
            if ($passwordCrypt->passwordVerify($password, $passwordEntity->getPassword())) {
                return true;
            }
        }

        return false;
    }

    /**
     * @param integer $size
     */
    public function setHistorySize($size)
    {
        $this->historySize = $size;
    }

    /**
     * @param string $userGuid
     */
    public function cleanUp($userGuid)
    {
        $passwords = $this->dbManager->webservice()->passwordHistory()->getPasswords($userGuid);
        while (count($passwords) > max($this->historySize, 1)) {
            $this->dbManager->webservice()->passwordHistory()->deletePassword(array_pop($passwords));
        }
    }
}
