package it.mice.voila.runtime.springmvc.csrf;

import it.mice.voila.runtime.springmvc.taglibs.TagUtils;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.web.servlet.support.RequestDataValueProcessor;

/**
 * A <code>RequestDataValueProcessor</code> that pushes a hidden field with a CSRF token into forms.
 * This process implements the {@link #getExtraHiddenFields(HttpServletRequest)} method to push the
 * CSRF token obtained from {@link CSRFTokenManager}. To register this processor to automatically process all
 * Spring based forms register it as a Spring bean named 'requestDataValueProcessor' as shown below:
 * <pre>
 *  &lt;bean name="requestDataValueProcessor" class="it.mice.voila.runtime.springmvc.csrf.CSRFRequestDataValueProcessor"/&gt;
 * </pre>
 * @author Eyal Lupu
 *
 */
public class CSRFRequestDataValueProcessor implements RequestDataValueProcessor {

    /**
     * Default logger.
     */
    private static final Log LOGGER = LogFactory.getLog(CSRFRequestDataValueProcessor.class); // NOSONAR
    
    private final CsrfTokenRepository csrfTokenRepository;
    
    public CSRFRequestDataValueProcessor(CsrfTokenRepository csrfTokenRepository) {
        this.csrfTokenRepository = csrfTokenRepository;
    }
    
	public String processAction(HttpServletRequest request, String action) {
		LOGGER.debug("processAction: " + action);
		return action;
	}

	public String processFormFieldValue(HttpServletRequest request, String name, String value, String type) {
		if (value != null) {
			value = StringUtils.trimToEmpty(value);
		}
		LOGGER.debug("processFormFieldValue: name=" + name + ", value=" + value + ", type=" + type);
		TagUtils.getSecuritySessionBean().addFormField(name, value, type);
		return value;
	}

	public Map<String, String> getExtraHiddenFields(HttpServletRequest request) {
		Map<String, String> hiddenFields = new HashMap<String, String>();
		// Carica il token CSRF
        CsrfToken csrfToken = csrfTokenRepository.loadToken(request);
        if (csrfToken == null) {
            csrfToken = csrfTokenRepository.generateToken(request);
            csrfTokenRepository.saveToken(csrfToken, request, null);
        }

        // Aggiungi il token CSRF ai campi nascosti
        hiddenFields.put(csrfToken.getParameterName(), csrfToken.getToken());
//		hiddenFields.put(CSRFTokenManager.CSRF_PARAM_NAME, CSRFTokenManager.getTokenForSession(request.getSession()));
		return hiddenFields;
	}

	public String processUrl(HttpServletRequest request, String url) {
		LOGGER.debug("processUrl: " + url);
		return url;
	}

	@Override
	public String processAction(HttpServletRequest request, String action, String httpMethod) {
		// TODO Auto-generated method stub
		return action;
	}

}
