/*
 * 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.openjpa.persistence;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.persistence.CacheRetrieveMode;
import javax.persistence.CacheStoreMode;

import org.apache.openjpa.lib.util.StringUtil;
import org.apache.openjpa.kernel.DataCacheRetrieveMode;
import org.apache.openjpa.kernel.DataCacheStoreMode;

/**
 * Enumerates configuration property keys defined in JPA 2.0 Specification.
 * <br>
 * Provides static utility functions to read their values from supplied map of properties.
 * <br>
 * Provides static utility functions to convert them to values that are fit for OpenJPA implementation.  
 * <br>
 * @author Pinaki Poddar
 * @since 2.0.0
 *
 */
public class JPAProperties {
    private static final String REGEX_DOT           = "\\.";
    public static final String PREFIX              = "javax.persistence.";
    
    public static final String PROVIDER            = PREFIX + "provider";
    public static final String TRANSACTION_TYPE    = PREFIX + "transactionType";
    
    public static final String DATASOURCE          = PREFIX + "dataSource";
    public static final String DATASOURCE_JTA      = PREFIX + "jtaDataSource";
    public static final String DATASOURCE_NONJTA   = PREFIX + "nonJtaDataSource";
    
    public static final String JDBC_DRIVER          = PREFIX + "jdbc.driver";
    public static final String JDBC_URL             = PREFIX + "jdbc.url";
    public static final String JDBC_USER            = PREFIX + "jdbc.user";
    public static final String JDBC_PASSWORD        = PREFIX + "jdbc.password";
    
    public static final String LOCK_SCOPE           = PREFIX + "lock.scope";
    public static final String LOCK_TIMEOUT         = PREFIX + "lock.timeout";
    
    public static final String QUERY_TIMEOUT        = PREFIX + "query.timeout";
    
    public static final String CACHE_MODE           = PREFIX + "sharedCache.mode";
    public static final String CACHE_STORE_MODE     = PREFIX + "cache.storeMode";
    public static final String CACHE_RETRIEVE_MODE  = PREFIX + "cache.retrieveMode";
    
    public static final String VALIDATE_FACTORY     = PREFIX + "validation.factory";
    public static final String VALIDATE_MODE        = PREFIX + "validation.mode";
    public static final String VALIDATE_PRE_PERSIST = PREFIX + "validation.group.pre-persist";
    public static final String VALIDATE_PRE_REMOVE  = PREFIX + "validation.group.pre-remove";
    public static final String VALIDATE_PRE_UPDATE  = PREFIX + "validation.group.pre-update";
    public static final String VALIDATE_GROUP_DEFAULT = "javax.validation.groups.Default";
    
    private static Map<String,String> _names = new HashMap<String, String>();
    
    /**
     * Record the given kernel property key (which is a bean property name without any suffix)
     * corresponding to the given original JPA/OpenJPA property used by the user to set the values.
     */
    static void record(String kernel, String user) {
        _names.put(kernel, user);
    }
    
    /**
     * Gets the original JPA Property name corresponding to the kernel property key 
     * (which is a bean property name without any suffix).
     */
    static String getUserName(String beanProperty) {
        return _names.containsKey(beanProperty) ? _names.get(beanProperty) : beanProperty;
    }
    
    /**
     * Is the given key appears to be a valid JPA specification defined key?
     * 
     * @return true if the given string merely prefixed with <code>javax.persistence.</code>.
     * Does not really check all the keys defined in the specification.
     */
    public static boolean isValidKey(String key) {
        return key != null && key.startsWith(PREFIX);
    }
    
    /**
     * Gets a bean-style property name from the given key.
     * 
     * @param key must begin with JPA property prefix <code>javax.persistence</code>
     * 
     * @return concatenates each part of the string leaving out <code>javax.persistence.</code> prefix. 
     * Part of string is what appears between DOT character.
     */
    public static String getBeanProperty(String key) {
        if (!isValidKey(key))
            throw new IllegalArgumentException("Invalid JPA property " + key);
        String[] parts = key.split(REGEX_DOT);
        StringBuilder buf = new StringBuilder();
        for (int i = 2; i < parts.length; i++) {
            buf.append(StringUtil.capitalize(parts[i]));
        }
        return buf.toString();
    }
    
    /**
     * Convert the given user value to a value consumable by OpenJPA kernel constructs.
     * 
     * @return the same value if the given key is not a valid JPA property key or the value is null.
     */
    public static <T> T  convertToKernelValue(Class<T> resultType, String key, Object value) {
        if (value == null)
            return null;
        if (JPAProperties.isValidKey(key)) {
            // works because enum values are identical String
            if (value instanceof CacheRetrieveMode || (value instanceof String && CACHE_RETRIEVE_MODE.equals(key))) {
                return (T)DataCacheRetrieveMode.valueOf(value.toString().trim().toUpperCase(Locale.ENGLISH));
            } else if (value instanceof CacheStoreMode || (value instanceof String && CACHE_STORE_MODE.equals(key))) {
                return (T)DataCacheStoreMode.valueOf(value.toString().trim().toUpperCase(Locale.ENGLISH));
            }
        }
        return (T)value;
    }
    
    /**
     * Convert the given kernel value to a value visible to the user.
     * 
     * @return the same value if the given key is not a valid JPA property key or the value is null.
     */
    public static Object convertToUserValue(String key, Object value) {
        if (value == null)
            return null;
        if (JPAProperties.isValidKey(key)) {
            // works because enum values are identical String
            if (value instanceof DataCacheRetrieveMode) {
                return CacheRetrieveMode.valueOf(value.toString().trim().toUpperCase(Locale.ENGLISH));
            } else if (value instanceof DataCacheStoreMode) {
                return CacheStoreMode.valueOf(value.toString().trim().toUpperCase(Locale.ENGLISH));
            }
        }
        return value;
    }
    
    /**
     * Get the value of the given key from the given properties after converting it to the given
     * enumerated value.
     */
    public static <E extends Enum<E>> E getEnumValue(Class<E> type, String key, Map<String,Object> prop) {
        return getEnumValue(type, null, key, prop);
    }
    
    /**
     * Gets a enum value of the given type from the given properties looking up with the given key.
     * Converts the original value from a String or ordinal number, if necessary.
     * Conversion from an integral number to enum value is only attempted if the allowed enum values
     * are provided as non-null, non-empty array. 
     * 
     * @return null if the key does not exist in the given properties.
     */
    public static <E extends Enum<E>> E getEnumValue(Class<E> type, E[] values, String key, Map<String,Object> prop) {
        if (prop == null)
            return null;
        return getEnumValue(type, values, prop.get(key));
    }
    
    /**
     * Gets a enum value of the given type from the given value.
     * Converts the original value from a String, if necessary.
     * 
     * @return null if the key does not exist in the given properties.
     */
    public static <E extends Enum<E>> E  getEnumValue(Class<E> type, Object val) {
        return getEnumValue(type, null, val);
    }
    
    /**
     * Gets a enum value of the given type from the given value.
     * Converts the original value from a String or ordinal number, if necessary.
     * Conversion from an integral number to enum value is only attempted if the allowed enum values
     * are provided as non-null, non-empty array. 
     * 
     * @return null if the key does not exist in the given properties.
     */
    public static <E extends Enum<E>> E  getEnumValue(Class<E> type, E[] values, Object val) {
        if (val == null)
            return null;
        if (type.isInstance(val))
            return (E)val;
        if (val instanceof String) {
            return Enum.valueOf(type, val.toString().trim().toUpperCase(Locale.ENGLISH));
        }
        if (values != null && values.length > 0 && val instanceof Number) {
            return values[((Number)val).intValue()];
        }
        return null; 
    }
}
