package com.util;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

@Component
public class CaptchaValidator {
	
	private String captchaService;
	private String captchaPublicKey;
	private String captchajs;
    
    
    private static final Integer TIMEOUT = 5000; // 5 seconds
    private static final Integer MAX_CONNECTIONS = 10;

    private final HttpClient httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
    private URL captchaServiceURL;

    public void init() throws MalformedURLException  {
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(TIMEOUT);
        httpClient.getHttpConnectionManager().getParams().setSoTimeout(TIMEOUT);
        httpClient.getHttpConnectionManager().getParams().setMaxTotalConnections(MAX_CONNECTIONS);
        captchaServiceURL = new URL(captchaService);
    }   
    

    public List<String> validate(String captchaChallenge, String captchaText) throws Exception {
    	List<String> errors = new ArrayList<String>();
        
        if (StringUtils.isBlank(captchaText)) {
            errors.add("NotBlank.captcha.response");
            return errors;
        }

        NameValuePair[] nameValuePairs = new NameValuePair[5];
        nameValuePairs[0] = new NameValuePair("public_key", captchaPublicKey);
        nameValuePairs[1] = new NameValuePair("client_ip_address","");
        nameValuePairs[2] = new NameValuePair("challenge_token",captchaChallenge);
        nameValuePairs[3] = new NameValuePair("user_answer", captchaText);
        nameValuePairs[4] = new NameValuePair("json", "false");
        
        HttpMethod method = new GetMethod(captchaServiceURL.toString());

        method.setQueryString(nameValuePairs);

        String response = "";
        try {
            int returnCode = httpClient.executeMethod(method);
            if (returnCode == HttpStatus.SC_OK) {
                response = method.getResponseBodyAsString();
            } else {
               System.out.println("CAPTCHA Service returned HttpStatus Code: " + returnCode);
            }
        } catch (Exception e) {
           System.out.println("Exception when invoking CAPTCHA Service"+e);
        } finally {
            method.releaseConnection();
            // Closes idle connections
            httpClient.getHttpConnectionManager().closeIdleConnections(0L);
        }

        // Parse response
        String lines[] = response.split("\\r?\\n");
        if (lines[0].equalsIgnoreCase("true")) {
            return Collections.emptyList();
        } else {
            String error = lines[1];
            if (error.equalsIgnoreCase("invalid-key")) {
                System.out.println("The CAPTCHA Service public key is incorrect.");
                errors.add(error);
            } else if (error.equalsIgnoreCase("invalid-parameters")) {
               System.out.println("The CAPTCHA Service was invoked with incorrect parameters.");
               errors.add(error);
            } else if (error.equalsIgnoreCase("unknown-error")) {
               System.out.println("The CAPTCHA Service returned an unknown error.");
               errors.add(error);
            } else if (error.equalsIgnoreCase("incorrect-captcha-sol")) {
                System.out.println("The letters in the graphic were entered incorrectly. Please try again.");
                errors.add(error);
             } else {
                errors.add(error);
            }                        
        }

        return errors;
    }


	/**
	 * @return the captchaService
	 */
	public String getCaptchaService() {
		return captchaService;
	}


	/**
	 * @param captchaService the captchaService to set
	 */
	public void setCaptchaService(String captchaService) {
		this.captchaService = captchaService;
	}


	/**
	 * @return the captchaPublicKey
	 */
	public String getCaptchaPublicKey() {
		return captchaPublicKey;
	}


	/**
	 * @param captchaPublicKey the captchaPublicKey to set
	 */
	public void setCaptchaPublicKey(String captchaPublicKey) {
		this.captchaPublicKey = captchaPublicKey;
	}


	/**
	 * @return the captchaServiceURL
	 */
	public URL getCaptchaServiceURL() {
		return captchaServiceURL;
	}


	/**
	 * @param captchaServiceURL the captchaServiceURL to set
	 */
	public void setCaptchaServiceURL(URL captchaServiceURL) {
		this.captchaServiceURL = captchaServiceURL;
	}


	/**
	 * @return the captchajs
	 */
	public String getCaptchajs() {
		return captchajs;
	}


	/**
	 * @param captchajs the captchajs to set
	 */
	public void setCaptchajs(String captchajs) {
		this.captchajs = captchajs;
	}


	
}
