class CustomerFacadeImpl implements CustomerFacade {

	@Autowired
	private com.salesmanager.shop.store.controller.customer.facade.CustomerFacade customerFacade;

	@Autowired
	private CustomerService customerService;

	@Autowired
	private FilePathUtils filePathUtils;

	@Autowired
	private LanguageService lamguageService;

	@Autowired
	private EmailUtils emailUtils;

	@Autowired
	private EmailService emailService;

	@Autowired
	@Qualifier("img")
	private ImageFilePath imageUtils;

	@Inject
	private LabelUtils messages;

	@Inject
	private PasswordEncoder passwordEncoder;

	private static final String resetCustomerLink = "customer/%s/reset/%s"; // front
																			// url

	private static final String ACCOUNT_PASSWORD_RESET_TPL = "email_template_password_reset_request_customer.ftl";

	private static final String RESET_PASSWORD_LINK = "RESET_PASSWORD_LINK";

	private static final String RESET_PASSWORD_TEXT = "RESET_PASSWORD_TEXT";

	@Override
	public void authorize(Customer customer, Principal principal) {

		Validate.notNull(customer, "Customer cannot be null");
		Validate.notNull(principal, "Principal cannot be null");

		if (!principal.getName().equals(customer.getNick())) {
			throw new UnauthorizedException(
					"User [" + principal.getName() + "] unauthorized for customer [" + customer.getId() + "]");
		}

	}

	@Override
	public void requestPasswordReset(String customerName, String customerContextPath, MerchantStore store,
			Language language) {<FILL_FUNCTION_BODY>}

	@Async
	private void resetPasswordRequest(Customer customer, String resetLink, MerchantStore store, Locale locale)
			throws Exception {
		try {

			// creation of a user, send an email
			String[] storeEmail = { store.getStoreEmailAddress() };

			Map<String, String> templateTokens = emailUtils.createEmailObjectsMap(imageUtils.getContextPath(), store,
					messages, locale);
			templateTokens.put(EmailConstants.LABEL_HI, messages.getMessage("label.generic.hi", locale));
			templateTokens.put(EmailConstants.EMAIL_CUSTOMER_FIRSTNAME, customer.getBilling().getFirstName());
			templateTokens.put(RESET_PASSWORD_LINK, resetLink);
			templateTokens.put(RESET_PASSWORD_TEXT,
					messages.getMessage("email.reset.password.text", new String[] { store.getStorename() }, locale));
			templateTokens.put(EmailConstants.LABEL_LINK_TITLE,
					messages.getMessage("email.link.reset.password.title", locale));
			templateTokens.put(EmailConstants.LABEL_LINK, messages.getMessage("email.link", locale));
			templateTokens.put(EmailConstants.EMAIL_CONTACT_OWNER,
					messages.getMessage("email.contactowner", storeEmail, locale));

			Email email = new Email();
			email.setFrom(store.getStorename());
			email.setFromEmail(store.getStoreEmailAddress());
			email.setSubject(messages.getMessage("email.link.reset.password.title", locale));
			email.setTo(customer.getEmailAddress());
			email.setTemplateName(ACCOUNT_PASSWORD_RESET_TPL);
			email.setTemplateTokens(templateTokens);

			emailService.sendHtmlEmail(store, email);

		} catch (Exception e) {
			throw new Exception("Cannot send email to customer", e);
		}
	}

	@Override
	public void verifyPasswordRequestToken(String token, String store) {
		Validate.notNull(token, "ResetPassword token cannot be null");
		Validate.notNull(store, "Store code cannot be null");

		verifyCustomerLink(token, store);
		return;
	}

	@Override
	public void resetPassword(String password, String token, String store) {
		Validate.notNull(token, "ResetPassword token cannot be null");
		Validate.notNull(store, "Store code cannot be null");
		Validate.notNull(password, "New password cannot be null");

		Customer customer = verifyCustomerLink(token, store);// reverify
		customer.setPassword(passwordEncoder.encode(password));
		try {
			customerService.save(customer);
		} catch (ServiceException e) {
			throw new ServiceRuntimeException("Error while saving customer",e);
		}

	}

	private Customer verifyCustomerLink(String token, String store) {

		Customer customer = null;
		try {
			customer = customerService.getByPasswordResetToken(store, token);
			if (customer == null) {
				throw new ResourceNotFoundException(
						"Customer not fount for store [" + store + "] and token [" + token + "]");
			}

		} catch (Exception e) {
			throw new ServiceRuntimeException("Cannot verify customer token", e);
		}

		Date tokenExpiry = customer.getCredentialsResetRequest().getCredentialsRequestExpiry();

		if (tokenExpiry == null) {
			throw new GenericRuntimeException("No expiry date configured for token [" + token + "]");
		}

		if (!DateUtil.dateBeforeEqualsDate(new Date(), tokenExpiry)) {
			throw new GenericRuntimeException("Ttoken [" + token + "] has expired");
		}

		return customer;

	}

	@Override
	public boolean customerExists(String userName, MerchantStore store) {
	    return Optional.ofNullable(customerService.getByNick(userName, store.getId()))
	            .isPresent();
	}

}


		try {
			// get customer by user name
			Customer customer = customerService.getByNick(customerName, store.getId());

			if (customer == null) {
				throw new ResourceNotFoundException(
						"Customer [" + customerName + "] not found for store [" + store.getCode() + "]");
			}

			// generates unique token
			String token = UUID.randomUUID().toString();

			Date expiry = DateUtil.addDaysToCurrentDate(2);

			CredentialsReset credsRequest = new CredentialsReset();
			credsRequest.setCredentialsRequest(token);
			credsRequest.setCredentialsRequestExpiry(expiry);
			customer.setCredentialsResetRequest(credsRequest);

			customerService.saveOrUpdate(customer);

			// reset password link
			// this will build http | https ://domain/contextPath
			String baseUrl = filePathUtils.buildBaseUrl(customerContextPath, store);

			// need to add link to controller receiving user reset password
			// request
			String customerResetLink = new StringBuilder().append(baseUrl)
					.append(String.format(resetCustomerLink, store.getCode(), token)).toString();

			resetPasswordRequest(customer, customerResetLink, store, lamguageService.toLocale(language, store));

		} catch (Exception e) {
			throw new ServiceRuntimeException("Error while executing resetPassword request", e);
		}

		/**
		 * User sends username (unique in the system)
		 * 
		 * UserNameEntity will be the following { userName: "test@test.com" }
		 * 
		 * The system retrieves user using userName (username is unique) if user
		 * exists, system sends an email with reset password link
		 * 
		 * How to retrieve a User from userName
		 * 
		 * userFacade.findByUserName
		 * 
		 * How to send an email
		 * 
		 * 
		 * How to generate a token
		 * 
		 * Generate random token
		 * 
		 * Calculate token expiration date
		 * 
		 * Now + 48 hours
		 * 
		 * Update User in the database with token
		 * 
		 * Send reset token email
		 */

	
<no_super_class>