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

use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Sso\BackendBundle\Form;
use Sso\WebserviceBundle\Entity\ServiceProvider\Type;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Class TokenController
 * @package Sso\BackendBundle\Controller
 */
class TokenController extends WsAbstractController
{

    const FE_ENTITY = "entity";
    const TOKEN_ID = "tokenId";

    /**
     * @Route("/", name="_admin_backend_token_list")
     * @Template()
     */
    public function listAction()
    {
        // Prepare pager
        $controller = $this;
        $routeGenerator = function ($page) use ($controller) {
            return $controller->generateUrl('_admin_backend_token_list', array('page' => $page));
        };
        list($filterForm, $queryBuilder) = $this->filter(
            new Form\TokenFilterType(),
            $this->tokenHandler()->getRepository()
        );
        list($entities, $pagerHtml) = $this->paginator($queryBuilder, $routeGenerator);

        return [
            'tokens' => $entities,
            'pagerHtml' => $pagerHtml,
            'filterForm' => $filterForm->createView(),
        ];
    }

    /**
     * @Route("/", name="_admin_backend_token_edit")
     * @Template()
     * @param string $tokenId
     * @return Response
     * @throws NotFoundHttpException
     */
    public function editAction($tokenId)
    {
        $entity = $this->tokenHandler()->getTokenByToken($tokenId);
        if (!$entity) {
            throw $this->createNotFoundException('Token not found!');
        }

        $editForm = $this->createEditForm($entity);
        $deleteForm = $this->createDeleteForm($tokenId);

        return [
            static::FE_ENTITY => $entity,
            'edit_form' => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        ];
    }

    /**
     *
     * @return Response
     */
    public function newAction()
    {
        $entity = new Type\Token();
        $form = $this->createCreateForm($entity);

        return $this->render('SsoBackendBundle:Token:new.html.twig', [
            static::FE_ENTITY => $entity,
            'form' => $form->createView(),
        ]);
    }

    /**
     *
     * @param \Symfony\Component\HttpFoundation\Request $request
     * @return Response
     */
    public function createAction(Request $request)
    {
        $tokenModel = new \Sso\WebserviceBundle\Entity\ServiceProvider\Type\Token();

        $form = $this->createCreateForm($tokenModel);
        $form->handleRequest($request);

        if ($form->isValid()) {
            $this->tokenHandler()->saveToken($tokenModel);
            $this->get('session')->getFlashBag()->add('success', 'Token created success');

            return $this->redirect(
                $this->generateUrl('_admin_backend_token_show', [static::TOKEN_ID => $tokenModel->getServiceToken()])
            );
        }

        return $this->render('SsoBackendBundle:Token:new.html.twig', [
            static::FE_ENTITY => $tokenModel,
            'form' => $form->createView(),
        ]);
    }

    /**
     * @param \Symfony\Component\HttpFoundation\Request $request
     * @param string $tokenId
     * @return Response
     */
    public function updateAction(Request $request, $tokenId)
    {
        $entity = $this->tokenHandler()->getTokenByToken($tokenId);
        if (!$entity) {
            throw $this->createNotFoundException('Token not found!');
        }

        $editForm = $this->createEditForm($entity);
        $deleteForm = $this->createDeleteForm($tokenId);
        $editForm->handleRequest($request);

        if ($editForm->isValid()) {
            $this->tokenHandler()->saveToken($entity);
            $this->get('session')->getFlashBag()->add('info', 'Token Saved Sucess');

            return $this->redirect($this->generateUrl('_admin_backend_token_edit', [static::TOKEN_ID => $tokenId]));
        } else {
            $this->get('session')->getFlashBag()->add('info', 'Token Saved Sucess');
        }

        return $this->render('SsoBackendBundle:Token:edit.html.twig', [
            static::FE_ENTITY => $entity,
            'edit_form' => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        ]);
    }

    /**
     * Creates a form to edit a User entity.
     * @param Type\Token $entity The entity
     * @return \Symfony\Component\Form\Form The form
     */
    private function createEditForm(Type\Token $entity)
    {
        $form = $this->createForm(
            new Form\TokenType(),
            $entity,
            [
                'action' => $this->generateUrl(
                    '_admin_backend_token_update',
                    [static::TOKEN_ID => $entity->getServiceToken()]
                ),
                'method' => 'PUT',
            ]
        );

        $form->add('submit', 'submit', array('label' => 'Update'));

        return $form;
    }

    /**
     * Creates a form to create a UserType entity.
     * @param Type\User $entity The entity
     * @return \Symfony\Component\Form\Form The form
     */
    private function createCreateForm(Type\Token $entity)
    {
        $form = $this->createForm(new Form\TokenType(), $entity, [
            'action' => $this->generateUrl('_admin_backend_token_create'),
            'method' => 'POST',
        ]);

        $form->add('submit', 'submit', array('label' => 'Create'));
        $form->add('ServiceToken', 'text', ['data' => $this->generateRandomToken()]);

        return $form;
    }

    /**
     * Creates a form to delete a User entity by id.
     * @param mixed $userId The entity id
     * @return \Symfony\Component\Form\Form
     */
    private function createDeleteForm($tokenId)
    {
        return $this->createFormBuilder()
            ->setAction($this->generateUrl('_admin_backend_token_delete', [static::TOKEN_ID => $tokenId]))
            ->setMethod('DELETE')
            ->add('submit', 'submit', ['label' => 'Delete'])
            ->getForm();
    }

    /**
     * @param \Symfony\Component\HttpFoundation\Request $request
     * @param string $tokenId
     * @return RedirectResponse
     * @throws NotFoundHttpException
     */
    public function deleteAction(Request $request, $tokenId)
    {
        $form = $this->createDeleteForm($tokenId);
        $form->handleRequest($request);
        $entity = $this->tokenHandler()->getTokenByToken($tokenId);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Token entity.');
        }

        $this->tokenHandler()->deleteToken($entity);
        $this->get('session')->getFlashBag()->add('success', 'Token deleted.');

        return $this->redirect($this->generateUrl('_admin_backend_token_list'));
    }

    /**
     * @param string $tokenId
     * @return Response
     * @throws NotFoundHttpException
     */
    public function showAction($tokenId)
    {
        $entity = $this->tokenHandler()->getTokenByToken($tokenId);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find token entity.');
        }

        $deleteForm = $this->createDeleteForm($tokenId);

        return $this->render('SsoBackendBundle:Token:show.html.twig', [
            static::FE_ENTITY => $entity,
            'delete_form' => $deleteForm->createView(),
        ]);
    }

    /**
     * @return string 1024 Bit
     */
    protected function generateRandomToken()
    {
        // first 16 chars
        $startRandom = $this->generateRandomString(48);

        // middle 32 chars
        $time = microtime();
        $middleRandom = md5($time);

        //end 16 chars
        $endRandom = $this->generateRandomString(48);

        // 128 Byte
        // 1024 Bit
        return $startRandom . $middleRandom . $endRandom;
    }

    /**
     * @param int $length
     * @return string
     */
    protected function generateRandomString($length)
    {
        $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
        $randomString = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[rand(0, strlen($characters) - 1)];
        }

        return $randomString;
    }

    /**
     * @return \Sso\WebserviceBundle\Database\ServiceProvider\Token Database handler for Token model
     */
    private function tokenHandler()
    {
        return $this->databaseManager()->serviceProvider()->token();
    }
}
