/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF 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.apache.myfaces.tomahawk.config;

import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

/**
 *
 * @author lu4242
 */
public class TomahawkConfig
{
    private static final String APPLICATION_MAP_PARAM_NAME = TomahawkConfig.class.getName();
    
    /**
     * If the param is set to true (default), a prefix is added to the captcha session key
     * used to store into session the secret generated by t:captcha component.
     * 
     * In versions before 1.1.14, the captcha session key is not prefixed, so it is possible
     * to override session values with random content, so this param is here by backward
     * compatibility with previous code that relies on such behavior.
     * 
     * @JSFWebConfigParam since="1.1.14" 
     *                    defaultValue="true"
     *                    expectedValues="true, false"
     */
    private static final String  INIT_PARAM_PREFIX_CAPTCHA_SESSION_KEY = "org.apache.myfaces.tomahawk.PREFIX_CAPTCHA_SESSION_KEY";
    private static final boolean INIT_PARAM_PREFIX_CAPTCHA_SESSION_KEY_DEFAULT = true;

    private boolean prefixCaptchaSessionKey;

    public TomahawkConfig()
    {
        setPrefixCaptchaSessionKey(INIT_PARAM_PREFIX_CAPTCHA_SESSION_KEY_DEFAULT);
    }
    
    public static TomahawkConfig getCurrentInstance(FacesContext facesContext)
    {
        return getCurrentInstance(facesContext.getExternalContext());
    }
    
    public static TomahawkConfig getCurrentInstance(ExternalContext extCtx)
    {
        TomahawkConfig myfacesConfig = (TomahawkConfig)extCtx
                                        .getApplicationMap().get(APPLICATION_MAP_PARAM_NAME);
        if (myfacesConfig == null) 
        {
            
            myfacesConfig = createAndInitializeTomahawkConfig(extCtx);
            
            extCtx.getApplicationMap().put(APPLICATION_MAP_PARAM_NAME, myfacesConfig);
            
        }

        return myfacesConfig;

    }
    
    private static TomahawkConfig createAndInitializeTomahawkConfig(ExternalContext extCtx)
    {
        TomahawkConfig config = new TomahawkConfig();
        
        config.setPrefixCaptchaSessionKey(getBooleanInitParameter(
                extCtx, INIT_PARAM_PREFIX_CAPTCHA_SESSION_KEY,
                INIT_PARAM_PREFIX_CAPTCHA_SESSION_KEY_DEFAULT));
        
        return config;
    }

    private static boolean getBooleanInitParameter(ExternalContext externalContext,
                                                   String paramName,
                                                   boolean defaultValue)
    {
        String strValue = externalContext.getInitParameter(paramName);
        if (strValue == null)
        {
            //if (log.isLoggable(Level.INFO)) log.info("No context init parameter '" + 
            // paramName + "' found, using default value " + defaultValue);
            return defaultValue;
        }
        else if (strValue.equalsIgnoreCase("true") || strValue.equalsIgnoreCase("on") || 
                strValue.equalsIgnoreCase("yes"))
        {
            return true;
        }
        else if (strValue.equalsIgnoreCase("false") || strValue.equalsIgnoreCase("off") || 
                strValue.equalsIgnoreCase("no"))
        {
            return false;
        }
        else
        {
            //if (log.isLoggable(Level.WARNING)) log.warning("Wrong context init parameter '" + 
            //paramName + "' (='" + strValue + "'), using default value " + defaultValue);
            return defaultValue;
        }
    }

    private static String getStringInitParameter(ExternalContext externalContext,
                                                 String paramName,
                                                 String defaultValue)
    {
        String strValue = externalContext.getInitParameter(paramName);
        if (strValue == null)
        {
            //if (log.isLoggable(Level.INFO)) log.info("No context init parameter '" + paramName +
            //"' found, using default value " + defaultValue); //defaultValue==null should not be 
            //a problem here
            return defaultValue;
        }
        
        return strValue;
    }

    private static long getLongInitParameter(ExternalContext externalContext,
                                                  String paramName,
                                                  long defaultValue)
    {
       String strValue = externalContext.getInitParameter(paramName);
       if (strValue == null)
       {
           //if (log.isLoggable(Level.INFO)) log.info("No context init parameter '" +paramName +
           //"' found, using default value " +defaultValue);
           return defaultValue;
       }
       else
       {
           try
           {
               return Long.parseLong(strValue);
           }
           catch (NumberFormatException e)
           {
               //if (log.isLoggable(Level.WARNING)) log.warning("Wrong context init parameter '" +
               //paramName + "' (='" + strValue + "'), using default value " + defaultValue);
           }
           return defaultValue;
       }
    }
    
    /**
     * @return the prefixCaptchaSessionKey
     */
    public boolean isPrefixCaptchaSessionKey()
    {
        return prefixCaptchaSessionKey;
    }

    /**
     * @param prefixCaptchaSessionKey the prefixCaptchaSessionKey to set
     */
    public void setPrefixCaptchaSessionKey(boolean prefixCaptchaSessionKey)
    {
        this.prefixCaptchaSessionKey = prefixCaptchaSessionKey;
    }
}
