/*
 * 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.empire.jsf2.utils;

import java.io.Serializable;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Hashtable;
import java.util.Locale;

import org.apache.empire.commons.DateUtils;
import org.apache.empire.commons.StringUtils;
import org.apache.empire.db.DBRowSet;
import org.apache.empire.exceptions.InternalException;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.UnexpectedReturnValueException;
import org.apache.empire.jsf2.pages.PageDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class manages request parameters in a way that they cannot be analyzed and modified by the user 
 * @author doebele
 *
 */
public class ParameterMap implements Serializable
{
    private static final long             serialVersionUID = 1L;

    private static final Logger           log              = LoggerFactory.getLogger(ParameterMap.class);

    private static final SimpleDateFormat dateFormat       = new SimpleDateFormat("yyyy.MM.dd hh:mm:ss", Locale.GERMAN);
    
    static private MessageDigest          md5              = null;
    {
        try
        {
            ParameterMap.md5 = MessageDigest.getInstance("MD5");
        }
        catch (NoSuchAlgorithmException e)
        {
            ParameterMap.log.error("MessageDigest NoSuchAlgorithmException.", e);
            throw new InternalException(e);
        }
    }
    
    private final byte[] salt;

    protected Hashtable<String, String> codeMap = new Hashtable<String, String>();

    protected final Hashtable<String, Hashtable<String, Object>> typeMap = new Hashtable<String, Hashtable<String, Object>>();
    
    public ParameterMap()
    {
        String dateTime = dateFormat.format(DateUtils.getTimeNow());
        salt = dateTime.getBytes();
    }
    
    public synchronized String encodeString(String valueAsString)
    {
        if (valueAsString==null)
            throw new InvalidArgumentException("valueAsString", valueAsString);
        // log
        if (log.isTraceEnabled())
            log.trace("Generating code for value {}.", valueAsString);
        // generate code
        md5.reset();
        if (salt!=null)
            md5.update(salt);
        md5.update(valueAsString.getBytes());
        byte s[] = ParameterMap.md5.digest();
        StringBuilder hash = new StringBuilder(32);
        for (int i = 0; i < s.length; i++)
        {   // add the hash part
            // String check = Integer.toHexString((0x000000ff & s[i]) | 0xffffff00).substring(6);;
            String part = Integer.toHexString(0x000000ff & s[i]);
            switch(part.length())
            {
                case 1: hash.append('0');
                case 2: hash.append(part);
                        break;
                default:
                        throw new UnexpectedReturnValueException(part, "Integer.toHexString");
                        // hash.append(part.substring(2));
            }
        }
        return hash.toString();
    }

    public String encodeStringWithCache(String valueAsString)
    {
        String code = codeMap.get(valueAsString);
        if (code==null)
        {   // generate code
            code = encodeString(valueAsString);
            codeMap.put(valueAsString, code);
        }
        return code;
    }

    /**
     * gets a unique name for a given rowset  
     * @param rowset
     * @return a unique name for the given rowset
     */
    protected String getRowSetTypeName(DBRowSet rowset)
    {
        /*
         * alternatively use:
         *     rowset.getName();
         * or
         *     rowset.getFullName();
         */
        return rowset.getClass().getName();
    }

    /**
     * puts an object into the parameter map
     * @param typeName
     * @param id
     * @param value
     */
    protected void putValue(String typeName, String encodedId, Object item)
    {   // put in Table
        if (encodedId==null)
        {
            throw new InvalidArgumentException("encodedId", encodedId);
        }
        Hashtable<String, Object> map = typeMap.get(typeName);
        if (map==null)
        {   map = new Hashtable<String, Object>(1);
            typeMap.put(typeName, map);
        }
        map.put(encodedId, item);
    }
    
    /**
     * encodes the objectKey and stores the item in the parameter map
     * @param typeName
     * @param id
     * @param value
     */
    protected String encodeAndStore(String typeName, String objectKey, Object item, boolean useCache)
    {   // Generate the id
        String encodedId = (useCache ? encodeStringWithCache(objectKey) : encodeString(objectKey));
        // store
        putValue(typeName, encodedId, item);
        // return id
        return encodedId;
    }

    public String put(String type, String key, boolean useCache)
    {
        // Generate id and put in map
        return encodeAndStore(type, key, key, useCache);
    }

    /**
     * Puts an object into the paramter map that implements the ParameterObject interface  
     * @param paramObject
     * @return
     */
    public String put(ParameterObject paramObject)
    {
        String objectKey;
        // check param
        if (paramObject==null || StringUtils.isEmpty((objectKey=paramObject.getObjectKey())))
            throw new InvalidArgumentException("paramObject", paramObject);
        // Generate id and put in map
        String type = paramObject.getClass().getName();
        return encodeAndStore(type, objectKey, paramObject, false);
    }

    public String put(DBRowSet rowset, Object[] key)
    {
        // Generate id and put in map
        String rowKey = StringUtils.valueOf(key);
        String type = getRowSetTypeName(rowset);
        return encodeAndStore(type, rowKey, key, false);
    }

    /*
     * do we really need this?
     * 
    public String put(Class<? extends Object> c, Object[] key)
    {
        // Generate id and put in map
        String ref = StringUtils.valueOf(key);
        String type = c.getName();
        return encodeAndStore(type, ref, key, false);
    }
    */
    
    /**
     * Generates an idParam which is only valid for the given page.
     * @param targetPage
     * @param rowset
     * @param key
     * @return
     */
    public String put(PageDefinition targetPage, DBRowSet rowset, Object[] key) {
        // Generate id and put in map
        String ref  = StringUtils.valueOf(key);
        String type = targetPage.getPageBeanName() + "$" + getRowSetTypeName(rowset);
        return encodeAndStore(type, ref, key, false);
    }

    /**
     * Gets an object from the parameter map for a given type and id
     * @param type the object type (typically the class name)
     * @param id the encoded idParam
     * @return the object
     */
    public Object get(String type, String id)
    {
        Hashtable<String, Object> map = typeMap.get(type);
        return (map!=null ? map.get(id) : null);
    }

    public void clear(String type)
    {
        Hashtable<String, Object> map = typeMap.get(type);
        if (map!=null)
            map.clear();
    }

    /**
     * Puts an object into the paramter map that implements the ParameterObject interface  
     * @param paramType
     * @param id
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T extends ParameterObject> T get(Class<T> paramType, String id)
    {
        String type = paramType.getName();
        Hashtable<String, Object> map = typeMap.get(type);
        return (T)(map!=null ? map.get(id) : null);
    }

    public void clear(Class<? extends ParameterObject> paramType)
    {
        String type = paramType.getName();
        clear(type);
    }

    /*
     * do we really need this?
     * 
    public Object[] getKey(Class<? extends Object> c, String id)
    {
        String type = c.getName();
        Hashtable<String, Object> map = typeMap.get(type);
        return (map!=null ? ((Object[])map.get(id)) : null);
    }
    */

    public Object[] getKey(DBRowSet rowset, String id)
    {
        String type = getRowSetTypeName(rowset);
        Hashtable<String, Object> map = typeMap.get(type);
        return (map!=null ? ((Object[])map.get(id)) : null);
    }

    public void clear(DBRowSet rowset)
    {
        String type = getRowSetTypeName(rowset);
        clear(type);
    }

    /**
     * returns an record key for a given page
     * @param page
     * @param rowset
     * @param id
     * @return
     */
    public Object[] getKey(PageDefinition page, DBRowSet rowset, String id)
    {
        String type = page.getPageBeanName() + "$" + getRowSetTypeName(rowset);
        Hashtable<String, Object> map = typeMap.get(type);
        return (map!=null ? ((Object[])map.get(id)) : null);
    }
}
