/*
 * The contents of this file are subject to the terms
 * of the Common Development and Distribution License
 * (the License).  You may not use this file except in
 * compliance with the License.
 *
 * You can obtain a copy of the license at
 * https://glassfish.dev.java.net/public/CDDLv1.0.html or
 * glassfish/bootstrap/legal/CDDLv1.0.txt.
 * See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL
 * Header Notice in each file and include the License file
 * at glassfish/bootstrap/legal/CDDLv1.0.txt.
 * If applicable, add the following below the CDDL Header,
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * Copyright (c) Ericsson AB, 2004-2007. All rights reserved.
 */
package com.ericsson.ssa.config;

import com.sun.enterprise.web.session.PersistenceType;
import com.sun.enterprise.ee.web.sessmgmt.EEPersistenceTypeResolver;

public class SipPersistenceStrategyBuilderFactory {
    private static String sipReplicationBuilderPath = null;

    static {
        try {
            sipReplicationBuilderPath = Class.forName(
                    "org.jvnet.glassfish.comms.replication.initialization.ReplicatedSipTransactionModifiedSessionStrategyBuilder")
                                             .getPackage().getName();
        } catch (ClassNotFoundException cnfe) {
            throw new ExceptionInInitializerError(cnfe);
        }
    }

    private EEPersistenceTypeResolver persistenceTypeResolver;

    /**
     * Constructor.
     */
    public SipPersistenceStrategyBuilderFactory() {
        persistenceTypeResolver = new EEPersistenceTypeResolver();
    }

    /**
     * Creates and returns the appropriate implementation of a
     * PersistenceStrategyBuilder.
     *
     * @param type Persistence type
     * @param frequency Persistence frequency
     * @param scope Persistence scope
     * @param ctxt
     */
    SipPersistenceStrategyBuilder createPersistenceStrategyBuilder(
        String persistenceType, String frequency, String scope,
        ConvergedContext ctxt) {

        String resolvedPersistenceFrequency = null;
        String resolvedPersistenceScope = null;
        String resolvedPersistenceType =
            persistenceTypeResolver.resolvePersistenceType(persistenceType);

        if (!resolvedPersistenceType.equalsIgnoreCase("memory")) {
            resolvedPersistenceFrequency = frequency;
            resolvedPersistenceScope = scope;
        }
 
        SipPersistenceStrategyBuilder builder = new MemoryStrategyBuilder();
        String className = createBuilderClassNameFrom(
                    resolvedPersistenceType, resolvedPersistenceFrequency,
                    resolvedPersistenceScope);
        try {
            builder = (SipPersistenceStrategyBuilder) Class.forName(className)
                                                           .newInstance();
        } catch (Exception ex) {
            // Fall back to memory
            // XXX LOG WARNING
            /*
            Object[] params = { getApplicationId(ctxt), persistenceType,
                                frequency, scope };
            */
        }

        builder.setPassedInPersistenceType(persistenceType);

        return builder;
    }

    /**
     * Determines an appropriately camel-cased string that is a candidate
     * class name for a builder.
     *
     * @param type Persistence type
     * @param frequency Persistence frequency
     * @param scope Persistence scope
     *
     * @return The class name of the builder
     */
    private String createBuilderClassNameFrom(String type, String frequency,
        String scope) {
        StringBuilder sb = new StringBuilder();
        sb.append(sipReplicationBuilderPath + ".");
        sb.append(camelCase(type));

        if (frequency != null) {
            sb.append(camelCase(frequency));
        }

        if (scope != null) {
            sb.append(camelCase(scope));
        }

        sb.append("StrategyBuilder");

        return sb.toString();
    }

    /**
     * Strips out all non-alpha characters from the given input string, and
     * camelCases the result.
     *
     * @param s The input string
     *
     * @return The camelCased result
     */
    private String camelCase(String s) {
        boolean toUpper = true;
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < s.length(); i++) {
            char nextChar = s.charAt(i);

            if (toUpper) {
                nextChar = Character.toUpperCase(nextChar);
                toUpper = false;
            }

            if (Character.isLetter(nextChar)) {
                sb.append(nextChar);
            } else {
                toUpper = true;
            }
        }

        return sb.toString();
    }
}
