<?php

namespace OfficeBrain\Bundle\UserBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\ExecutionContextInterface;
use OfficeBrain\Bundle\UserBundle\Entity\User;
use OfficeBrain\Bundle\UserBundle\Service\CustomPasswordEncoder;

class ChangePasswordType extends AbstractType
{
    protected $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }


    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    /*
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $constraints['password'] =  array(
                        new Assert\NotBlank(array('message' => 'user.change_password.password.not_blank')),
                        new Assert\Length(array('min'=>5, 'minMessage'=>'user.change_password.password.min')),
                        new Assert\Regex(array('pattern'=>'/^([a-zA-Z0-9@*#_]{5,25})$/', 'message'=>'user.change_password.password.invalid'))
                );

        $constraints['current_password'] = array(
                        new Assert\NotBlank(array('message' => 'user.change_password.current_password.not_blank')),
                        new Assert\Length(array('min'=>5, 'minMessage'=>'user.change_password.current_password.min')),
                        new Assert\Regex(array('pattern'=>'/^([a-zA-Z0-9@*#_]{5,25})$/', 'message'=>'user.change_password.current_password.invalid')),
                        new Assert\Callback(array('methods' => array( array($this, 'checkOldPassword') )))
                );


        $builder
            ->add('current_password', 'password', array(
                    'constraints' => $constraints['current_password'],
            ))
           ->add('password', 'repeated', array(
                    'type' => 'password',
                    'constraints'=>$constraints['password'],
                    'invalid_message' => 'user.change_password.password.mismatch',
            )
        );
    }
*/
    public function buildForm(FormBuilderInterface $builder, array $options) {
    
    	$constraints['password'] = array(
    			new Assert\NotBlank(array('message' => 'user.change_password.password.not_blank')),
    			new Assert\Length(array('min'=>8, 'minMessage'=>'user.password.min','max'=>25, 'maxMessage'=>'user.password.max')),
    			new Assert\Regex(array('pattern'=>'/^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*\W)(?!.* ).{8,25}$/', 'message'=>'user.password.invalid')),
    	);
    
    	$constraints['current_password'] = array(
    			new Assert\NotBlank(array('message' => 'user.change_password.current_password.not_blank')),
    			new Assert\Length(array('min'=>8, 'minMessage'=>'user.password.min','max'=>25, 'maxMessage'=>'user.password.max')),
    			new Assert\Regex(array('pattern'=>'/^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*\W)(?!.* ).{8,25}$/', 'message'=>'user.password.invalid')),
    			new Assert\Callback(array('methods' => array( array($this, 'compareOldAndNewPassword') ))),
    			new Assert\Callback(array('methods' => array( array($this, 'checkOldPassword') )))
    	);
    	$constraints['confirm_password'] = array(
    			new Assert\NotBlank(array('message' => 'user.change_password.confirm_password.not_blank')),
    			new Assert\Length(array('min'=>8, 'minMessage'=>'user.password.min','max'=>25, 'maxMessage'=>'user.password.max')),
    			new Assert\Regex(array('pattern'=>'/^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*\W)(?!.* ).{8,25}$/', 'message'=>'user.password.invalid')),
    	);
    	$constraints['new_password'] = array(
    			new Assert\NotBlank(array('message' => 'user.change_password.password.not_blank')),
    			new Assert\Length(array('min'=>8, 'minMessage'=>'user.password.min','max'=>25, 'maxMessage'=>'user.password.max')),
    			new Assert\Regex(array('pattern'=>'/^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*\W)(?!.* ).{8,25}$/', 'message'=>'user.password.invalid')),
    	);
    
    	$builder
    	->add('current_password', 'password', array('mapped' => true,
    			'constraints' => $constraints['current_password'],
    	))
    	->add('password', 'repeated', array(
    			'mapped' => true,
    			'type' => 'password',
    			'invalid_message' => 'user.change_password.password.mismatch',
    			'first_options' => array(
    					'constraints' => $constraints['new_password']
    			),
    			'second_options' => array(
    					'constraints' => $constraints['confirm_password']
    			)
    	)
    	);
    }
    /**
     * @return string
     */
    public function getName()
    {
        return 'ob_change_pwd';
    }



    /**
     * Checks current password is correct
     *
     * @param string $oldPassword
     * @param \Symfony\Component\Validator\ExecutionContextInterface $context
     */
    public function checkOldPassword($oldPassword, ExecutionContextInterface $context)
    {
        $encoder = new CustomPasswordEncoder();
        $encodedPassword = $encoder->encodePassword($oldPassword, $this->user->getSalt());
        if ($this->user->getPassword()!=$encodedPassword) {
            $context->addViolation('user.change_password.current_password.mismatch', array(), null);
        }
    }
    
    /**
     * Checks current password should not match with new password
     *
     * @param array $data
     * @param \Symfony\Component\Validator\ExecutionContextInterface $context
     */
    public function compareOldAndNewPassword($value, ExecutionContextInterface $context)
    {
    	$form = $context->getRoot();
    	if ($form->get('current_password')->getData()!='' && $form->get('password')['first']->getData() !='' && $form->get('current_password')->getData()==$form->get('password')['first']->getData()) {
    		$context->addViolation('user.change_password.current_password.should_not_match', array(), null);
    	}
    }
}
