/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2004 Bull S.A.
 * Contact: jonas-team@objectweb.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * Initial developer(s): Florent BENOIT
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */
package org.objectweb.jonas.db;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import javax.naming.Context;
import javax.naming.NamingException;

import org.objectweb.jonas.common.Log;
import org.objectweb.jonas.service.AbsServiceImpl;
import org.objectweb.jonas.service.ServiceException;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;

/**
 * Abstract database service to be implemented by implementation of Java
 * databases
 * @author Florent Benoit
 */
public abstract class AbsDBServiceImpl extends AbsServiceImpl {

    /**
     * Property for the port number
     */
    private static final String PORT_NUMBER = "port";

    /**
     * Property for the name of the database
     */
    private static final String DATABASE_NAME = "dbname";

    /**
     * Property for the default database name
     */
    private static final String DEFAULT_DATABASE_NAME = "db_jonas";

    /**
     * Property for looking up users (suffix by 1..n)
     */
    private static final String USERS = "user";

    /**
     * Logger used by this service
     */
    private static Logger logger = null;

    /**
     * Initialize the service.
     * @param ctx the configuration context of the service.
     * @throws ServiceException if the initialization failed.
     */

    protected void doInit(Context ctx) throws ServiceException {
        logger = Log.getLogger(Log.JONAS_DB_PREFIX);

        // Lookup port number
        String port = null;
        try {
            port = (String) ctx.lookup(PORT_NUMBER);
        } catch (NamingException ne) {
            logger.log(BasicLevel.INFO, "Use the default port as the property is missing in jonas.properties file");
        }

        // Database name
        String databaseName = null;
        try {
            databaseName = (String) ctx.lookup(DATABASE_NAME);
        } catch (NamingException ne) {
            logger.log(BasicLevel.INFO, "Use the default databsename '" + DEFAULT_DATABASE_NAME
                    + "' as the property is missing in jonas.properties file.");
            databaseName = DEFAULT_DATABASE_NAME;
        }

        // Users
        List users = new ArrayList();
        boolean hasUsers = true;
        int i = 1;
        while (hasUsers) {
            try {
                String usernameAndPass = (String) ctx.lookup(USERS + i);
                if (logger.isLoggable(BasicLevel.DEBUG)) {
                    logger.log(BasicLevel.DEBUG, "Adding user/password '" + usernameAndPass + "'.");
                }

                StringTokenizer st = new StringTokenizer(usernameAndPass, ":");
                String name = st.nextToken();
                String pass = "";
                if (st.hasMoreTokens()) {
                    pass = st.nextToken();
                }
                users.add(new User(name, pass));
            } catch (NamingException ne) {
                if (logger.isLoggable(BasicLevel.DEBUG)) {
                    logger.log(BasicLevel.DEBUG, "No more users (length =" + i + ").");
                }
                hasUsers = false;
            }
            i++;
        }

        initServer(users, databaseName, port);
    }

    /**
     * Create a database with the specified arguments. Need to be implemented by
     * classes extending this one.
     * @param users user/password (separated by a ":")
     * @param databaseName name of the database
     * @param portNumber port number of the database
     */
    protected abstract void initServer(List users, String databaseName, String portNumber);

    /**
     * Start the service.
     * @throws ServiceException if the startup failed.
     */
    protected void doStart() throws ServiceException {
        if (logger.isLoggable(BasicLevel.DEBUG)) {
            logger.log(BasicLevel.DEBUG, "");
        }
    }

    /**
     * Stop the service.
     * @throws ServiceException if the stop failed.
     */
    protected void doStop() throws ServiceException {
        if (logger.isLoggable(BasicLevel.DEBUG)) {
            logger.log(BasicLevel.DEBUG, "");
        }
    }

    /**
     * @return the logger.
     */
    public static Logger getLogger() {
        return logger;
    }
}