/*
 * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.wso2.carbon.identity.application.authentication.framework.inbound;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.identity.core.handler.InitConfig;
import org.wso2.carbon.identity.core.model.IdentityEventListenerConfig;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class HttpIdentityRequestFactory implements IdentityHandler{

    private static Log log = LogFactory.getLog(HttpIdentityRequestFactory.class);

    protected final Properties properties = new Properties();

    protected InitConfig initConfig;

    public static final String TENANT_DOMAIN_PATTERN = "/t/([^/]+)";

    public void init(InitConfig initConfig) {

        this.initConfig = initConfig;

        IdentityEventListenerConfig identityEventListenerConfig = IdentityUtil.readEventListenerProperty
                (HttpIdentityRequestFactory.class.getName(), this.getClass().getName());

        if (identityEventListenerConfig == null) {
            return;
        }

        if(identityEventListenerConfig.getProperties() != null) {
            for(Map.Entry<Object,Object> property:identityEventListenerConfig.getProperties().entrySet()) {
                String key = (String)property.getKey();
                String value = (String)property.getValue();
                if(!properties.containsKey(key)) {
                    properties.setProperty(key, value);
                } else {
                    log.warn("Property key " + key + " already exists. Cannot add property!!");
                }
            }
        }
    }

    public String getName() {
        return "HttpIdentityRequestFactory";
    }

    public int getPriority() {
        return 0;
    }

    public boolean canHandle(HttpServletRequest request, HttpServletResponse response) {
        return true;
    }

    public IdentityRequest.IdentityRequestBuilder create(HttpServletRequest request, HttpServletResponse response)
            throws FrameworkClientException {

        IdentityRequest.IdentityRequestBuilder builder = new IdentityRequest.IdentityRequestBuilder(request, response);
        Enumeration<String> headerNames = request.getHeaderNames();
        while(headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            builder.addHeader(headerName, request.getHeader(headerName));
        }
        builder.setParameters(request.getParameterMap());
        Cookie[] cookies = request.getCookies();
        if(cookies != null) {
            for (Cookie cookie : cookies) {
                builder.addCookie(cookie.getName(), cookie);
            }
        }
        String requestURI = request.getRequestURI();
        Pattern pattern = Pattern.compile(TENANT_DOMAIN_PATTERN);
        Matcher matcher = pattern.matcher(requestURI);
        if(matcher.find()) {
            builder.setTenantDomain(matcher.group(1));
        } else {
            builder.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
        }
        builder.setContentType(request.getContentType());
        builder.setContextPath(request.getContextPath());
        builder.setMethod(request.getMethod());
        builder.setPathInfo(request.getPathInfo());
        builder.setPathTranslated(request.getPathTranslated());
        builder.setQueryString(request.getQueryString());
        builder.setRequestURI(requestURI);
        builder.setRequestURL(request.getRequestURL());
        builder.setServletPath(request.getServletPath());
        return builder;
    }

    public void create(IdentityRequest.IdentityRequestBuilder builder,
                                                         HttpServletRequest request, HttpServletResponse response)
            throws FrameworkClientException {

        Enumeration<String> headerNames = request.getHeaderNames();
        while(headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            builder.addHeader(headerName, request.getHeader(headerName));
        }
        builder.setParameters(request.getParameterMap());
        Cookie[] cookies = request.getCookies();
        if(cookies!=null) {
            for (Cookie cookie : cookies) {
                builder.addCookie(cookie.getName(), cookie);
            }
        }
        String requestURI = request.getRequestURI();
        Pattern pattern = Pattern.compile(TENANT_DOMAIN_PATTERN);
        Matcher matcher = pattern.matcher(requestURI);
        if(matcher.find()) {
            builder.setTenantDomain(matcher.group(1));
        } else {
            builder.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
        }
        builder.setContentType(request.getContentType());
        builder.setContextPath(request.getContextPath());
        builder.setMethod(request.getMethod());
        builder.setPathInfo(request.getPathInfo());
        builder.setPathTranslated(request.getPathTranslated());
        builder.setQueryString(request.getQueryString());
        builder.setRequestURI(requestURI);
        builder.setRequestURL(request.getRequestURL());
        builder.setServletPath(request.getServletPath());

    }

    public HttpIdentityResponse.HttpIdentityResponseBuilder handleException(FrameworkClientException exception,
                                                                            HttpServletRequest request,
                                                                            HttpServletResponse response) {

        HttpIdentityResponse.HttpIdentityResponseBuilder builder = new HttpIdentityResponse.HttpIdentityResponseBuilder();
        builder.setStatusCode(400);
        builder.setBody(exception.getMessage());
        return builder;
    }
}

@@ -3155,1385 +3155,41 @@
     
-Enumeration%3CString%3E headerNames = request.getHeaderNames();%0A        while(headerNames.hasMoreElements()) %7B%0A            String headerName = headerNames.nextElement();%0A            builder.addHeader(headerName, request.getHeader(headerName));%0A        %7D%0A        builder.setParameters(request.getParameterMap());%0A        Cookie%5B%5D cookies = request.getCookies();%0A        if(cookies != null) %7B%0A            for (Cookie cookie : cookies) %7B%0A                builder.addCookie(cookie.getName(), cookie);%0A            %7D%0A        %7D%0A        String requestURI = request.getRequestURI();%0A        Pattern pattern = Pattern.compile(TENANT_DOMAIN_PATTERN);%0A        Matcher matcher = pattern.matcher(requestURI);%0A        if(matcher.find()) %7B%0A            builder.setTenantDomain(matcher.group(1));%0A        %7D else %7B%0A            builder.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);%0A        %7D%0A        builder.setContentType(request.getContentType());%0A        builder.setContextPath(request.getContextPath());%0A        builder.setMethod(request.getMethod());%0A        builder.setPathInfo(request.getPathInfo());%0A        builder.setPathTranslated(request.getPathTranslated());%0A        builder.setQueryString(request.getQueryString());%0A        builder.setRequestURI(requestURI);%0A        builder.setRequestURL(request.getRequestURL());%0A        builder.setServletPath(request.getServletPath()
+create(builder, request, response
 );%0A 

update HttpIdentityRequestFactory