package com.atlassian.bitbucket.web.cgi;

import com.atlassian.bitbucket.scm.CommandBuilder;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

public class CgiEnvironmentUtils {

    /**
     * Set environment variables specified in "The WWW Common Gateway Interface Version 1.1"
     *
     * @param builder an {@link com.atlassian.utils.process.ExternalProcessBuilder} to which to add standard CGI environment variables
     * @param request the context request
     * @param servletContext the servlet context
     */
    public static void applyStandardCgiEnvironment(CommandBuilder builder, HttpServletRequest request, ServletContext servletContext) {
        Map<String, String> cgiEnv = new HashMap<>();

        cgiEnv.put("AUTH_TYPE", request.getAuthType());
        cgiEnv.put("CONTENT_LENGTH", Integer.toString(Math.max(0, request.getContentLength())));
        cgiEnv.put("CONTENT_TYPE", request.getContentType());
        cgiEnv.put("GATEWAY_INTERFACE", "CGI/1.1");
        cgiEnv.put("QUERY_STRING", request.getQueryString());
        // n.b. REMOTE_USER is set by RemoteUserExternalProcessConfigurer in service-impl rather than here, so that it
        // is available to hooks invoked by SSH commands as well.
        cgiEnv.put("REMOTE_ADDR", request.getRemoteAddr());
        cgiEnv.put("REMOTE_HOST", request.getRemoteHost());
        cgiEnv.put("REQUEST_METHOD", request.getMethod());
        cgiEnv.put("SERVER_NAME", request.getServerName());
        cgiEnv.put("SERVER_PORT", Integer.toString(request.getServerPort()));
        cgiEnv.put("SERVER_PROTOCOL", request.getProtocol());
        cgiEnv.put("SERVER_SOFTWARE", servletContext.getServerInfo());
        Enumeration enm = request.getHeaderNames();
        while (enm.hasMoreElements()) {
            String name = (String) enm.nextElement();
            String value = request.getHeader(name);
            cgiEnv.put("HTTP_" + name.toUpperCase().replace('-', '_'), value);
        }
        cgiEnv.put("HTTPS", (request.isSecure() ? "ON" : "OFF"));

        cgiEnv.entrySet().stream()
                // command builder doesn't support blank environment variable values
                .filter(env -> StringUtils.isNotBlank(env.getValue()))
                .forEach(env -> builder.withEnvironment(env.getKey(), env.getValue()));
    }
}
