<?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 LifeStyle\Tools\CipheringBundle\Api\Ciphering\Configuration;

use Symfony\Component\DependencyInjection\ContainerInterface as Container;

/**
 * Class Index
 * @package LifeStyle\Tools\CipheringBundle\Api\Ciphering\Configuration
 */
class Index
{
    /**
     * @var Container
     */
    protected $container;

    /**
     * loaded from configuration
     * @var bool
     */
    private $openSslIsFallback;

    /**
     * loaded from configuration
     * @var array
     */
    private $openSslCipherNames;

    /**
     * loaded from configuration
     * @var string
     */
    private $mcryptCipherName;

    /**
     * loaded from configuration
     * @var string
     */
    private $mcryptModeName;

    /**
     * random generated string
     * @var string
     */
    private $mcryptitializationVector;

    /**
     * @var string
     */
    private $additionalKey;

    /**
     * @param Container $container
     */
    public function __construct(Container $container)
    {
        $this->container = $container;
        $configArray = $this->container->getParameter('life_style_tools_ciphering');

        // Open SSL (current)
        $this->openSslIsFallback = $this->parameterIsTrue($configArray['openssl_is_fallback']);
        $this->openSslCipherNames = $configArray['openssl_cypher_names'];

        // Mcrypt (deprecated)
        $this->mcryptCipherName = $configArray['mcrypt_cypher_name'];
        $this->mcryptModeName = $configArray['mcrypt_mode_name'];
        $this->additionalKey = $configArray['mcrypt_additional_key'];
        $this->setMcryptitializationVector();
    }

    /**
     * set mcryptitializationVector
     */
    private function setMcryptitializationVector()
    {
        if (function_exists('mcrypt_create_iv')) {
            $this->mcryptitializationVector = mcrypt_create_iv(mcrypt_get_iv_size(constant($this->mcryptCipherName), constant($this->mcryptModeName)), MCRYPT_DEV_URANDOM);
        }
    }

    /**
     * @return bool
     */
    public function isOpenSslFallback(): bool
    {
        return $this->openSslIsFallback;
    }

    /**
     * @return array
     */
    public function getOpenSslCipherNames()
    {
        return $this->openSslCipherNames;
    }

    /**
     * @return string
     */
    public function getMcryptCipherName()
    {
        return $this->mcryptCipherName;
    }

    /**
     * @return string
     */
    public function getMcryptModeName()
    {
        return $this->mcryptModeName;
    }

    /**
     * @return string
     */
    public function getMcryptitializationVector()
    {
        return $this->mcryptitializationVector;
    }

    /**
     * @return string
     */
    public function getAdditionalKey()
    {
        return $this->additionalKey;
    }

    /**
     * @param $flexKey
     * @param bool|false $addKey
     * @return string
     */
    public function keyMixer($flexKey, $addKey = false)
    {
        if ($addKey) {
            $tempKeyFixedArray = str_split($addKey);
        } else {
            $tempKeyFixedArray = str_split($this->additionalKey);
        }

        $tempKeyStaticArray = str_split($flexKey);
        $mixedKey = "";
        $i = 0;
        foreach ($tempKeyFixedArray as $char) {

            if (isset($tempKeyStaticArray[$i])) {
                $charAdd = $tempKeyStaticArray[$i] . $char;
            } else {
                $charAdd = $char;
            }

            if ($i % 2 != 0) {
                $mixedKey = $mixedKey . $charAdd;
            }

            //some additional trick
            if (($i * 2) == 42) {
                $mixedKey = $mixedKey . "o&s";
            }
            $i++;
        }
        return $mixedKey;
    }

    /**
     * Convert parameter into boolean
     *
     * @param mixed $parameter
     * @return bool
     */
    private function parameterIsTrue($parameter): bool
    {
        return $parameter === 1 ||
            $parameter === '1' ||
            $parameter === true ||
            strtolower($parameter) === 'true' ||
            strtolower($parameter) === 'yes';
    }
}

