package grails.plugin.multitenant.core;

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

import org.apache.log4j.Logger;

/**
 * Base class used for mapping sub-domains to tenantIds.  Subclasses can implement an "initialize" method
 * that loads the data into the "hosts" map, and this class will take care of the rest.  There is also a cache
 * that can be used to store all the domain information including the name and other information.
 */
public abstract class BaseDomainNameTenantResolver implements TenantResolver
{
    /**
     * This is a logger for logging status and error messages.
     */
    private static Logger log = Logger.getLogger(BaseDomainNameTenantResolver.class);
    /**
     * This is the name of the shared cache of tenant data.  This is a shared cache where domain objects are stored
     * with information about the existing tenants.
     */
    public static String TENANT_DATA_CACHE_NAME = "MultiTenantDomainData";
    /**
     * The map of hosts server names to tenant id used to look up tenant id.
     */
    protected Map<String, Integer> hosts = new HashMap<String, Integer>();
    // This is set to true if the data has been loaded and is current
    protected boolean loaded;

    /**
     * This will decode the tenantId based on the server name in the request.  It will return the mapped tenant id
     * based on the decoded server name or null if there is no match.  If there is no match the server name will be
     * output as a fatal error.  Debugging is available to output the tenant Id and matching server name.
     *
     * @param inRequest - The http servlet request to decode the tenant from.
     * @return - The tenant id based on the complete server name in the request.  Null if no match.
     */
    public Integer getTenantFromRequest(HttpServletRequest inRequest)
    {
        if (!loaded)
        {
            initialize();
            loaded = true;
        }
        Integer tenantId = hosts.get(inRequest.getServerName());
        if (tenantId == null)
        {
            log.fatal("Could not decode valid tenant id from request server " + inRequest.getServerName());
            throw new InvalidTenantException("Could not decode mapped tenant id from request server name " + inRequest.getServerName());
        }
        if (log.isDebugEnabled())
        {
            log.debug("Decoded tenant id " + tenantId + " from http request URL " + inRequest.getServerName());
        }
        return tenantId;
    }

    /**
     * Loads up all the mappings into the protected "hosts" field.  This can do other additional operations in the
     * super class.
     */
    public abstract void initialize();
}
@@ -1957,32 +1957,350 @@
 true;%0A        %7D%0A
+%0A%09%09String headerName = %22x-forwarded-host%22;%0A%09%09String currentServerName = inRequest.getServerName();%0A%09%09if (inRequest.getHeader(headerName) != null) %7B%0A%09%09%09currentServerName = inRequest.getHeader(headerName);%0A%09%09%09log.debug(%22http request URL %5B%22+currentServerName+%22%5D decoded using header %5B%22+headerName+%22%5D from request%22);%0A%09%09%7D%0A%0A
         Integer 
@@ -2320,28 +2320,22 @@
 sts.get(
-inRequest.ge
+curren
 tServerN
@@ -2329,34 +2329,32 @@
 urrentServerName
-()
 );%0A        if (t
@@ -2456,36 +2456,30 @@
  server %22 + 
-inRequest.ge
+curren
 tServerName(
@@ -2469,34 +2469,32 @@
 urrentServerName
-()
 );%0A            t
@@ -2585,36 +2585,30 @@
 er name %22 + 
-inRequest.ge
+curren
 tServerName(
@@ -2598,34 +2598,32 @@
 urrentServerName
-()
 );%0A        %7D%0A   
@@ -2747,28 +2747,22 @@
 URL %22 + 
-inRequest.ge
+curren
 tServerN
@@ -2764,18 +2764,16 @@
 rverName
-()
 );%0A     

fix for GRAILSPLUGINS-2774