/*
 *  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.commons.daemon.support;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Properties;
import java.text.ParseException;

/**
 * Used by jsvc for Daemon configuration.
 * <p>
 * Configuration is read from properties file.
 * If no properties file is given the {@code daemon.properties}
 * is used from the current directory.
 * </p>
 * <p>
 * The properties file can have property values expanded at runtime
 * by using System properties or execution environment. The part
 * of the property value between {@code ${} and {@code }}
 * will be used as System property or environment key. If found then
 * the entire {@code ${foo}} will be replaced by the value of
 * either system property or environment variable named {@code foo}.
 * </p>
 * <p>
 * If no variable is found the {@code ${foo}}  will be passed as is.
 * In case of {@code $${foo}} this will be unescaped and resulting
 * value will be {@code ${foo}}.
 * </p>
 *
 */
public final class DaemonConfiguration
{
    /**
     * Default configuration file name.
     */
    protected final static String DEFAULT_CONFIG        = "daemon.properties";
    /**
     * Property prefix
     */
    protected final static String PREFIX                = "daemon.";
    private   final static String BTOKEN                = "${";
    private   final static String ETOKEN                = "}";


    private final Properties configurationProperties;
    private final Properties systemProperties;

    /**
     * An empty immutable {@code String} array.
     */
    static final String[] EMPTY_STRING_ARRAY = new String[0];

    /**
     * Default constructor
     */
    public DaemonConfiguration()
    {
        configurationProperties = new Properties();
        systemProperties        = System.getProperties();
    }

    /**
     * Loads the configuration properties file.
     *
     * @param fileName The properties file to load.
     * @return {@code true} if the file was loaded.
     */
    public boolean load(String fileName)
    {
        boolean ok = false;
        FileInputStream file = null;
        try {
            if (fileName == null) {
                fileName = DEFAULT_CONFIG;
            }
            file = new FileInputStream(fileName);
            configurationProperties.clear();
            configurationProperties.load(file);
            ok = true;
        }
        catch (final IOException ex) {
            // Error reading properties file
        } finally {
            try {
                if (file != null) {
                    file.close();
                }
            } catch (final IOException ex) {
            }
        }
        return ok;
    }

    private String expandProperty(final String propValue)
        throws ParseException
    {
        final StringBuffer expanded;
        int btoken;
        int ctoken = 0;

        if (propValue == null) {
            return null;
        }
        expanded = new StringBuffer();
        btoken   = propValue.indexOf(BTOKEN);
        while (btoken != -1) {
            if (btoken > 0 && propValue.charAt(btoken - 1) == BTOKEN.charAt(0)) {
                // Skip and unquote.
                expanded.append(propValue.substring(ctoken, btoken));
                ctoken = btoken + 1;
                btoken = propValue.indexOf(BTOKEN, btoken + BTOKEN.length());
                continue;
            }
            final int etoken = propValue.indexOf(ETOKEN, btoken);
            if (etoken == -1) {
                // We have "${" without "}"
                throw new ParseException("Error while looking for teminating '" +
                                         ETOKEN + "'", btoken);
            }
            final String variable = propValue.substring(btoken + BTOKEN.length(), etoken);
            String sysvalue = systemProperties.getProperty(variable);
            if (sysvalue == null) {
                // Try with the environment if there was no
                // property by that name.
                sysvalue = System.getenv(variable); // N.B. Deprecated in Java 1.3/1.4, but re-instated in Java 1.5+
            }
            if (sysvalue != null) {
                final String strtoken = propValue.substring(ctoken, btoken);
                expanded.append(strtoken);
                expanded.append(sysvalue);
                ctoken = etoken + ETOKEN.length();
            }
            btoken = propValue.indexOf(BTOKEN, etoken + ETOKEN.length());
        }
        // Add what's left.
        expanded.append(propValue.substring(ctoken));
        return expanded.toString();
    }

    /**
     * Gets the configuration property.
     *
     * @param name The name of the property to get.
     *
     * @throws ParseException if the property is wrongly formatted.
     *
     * @return  Configuration property including any expansion/replacement
     */
    public String getProperty(final String name)
        throws ParseException
    {
        if (name == null) {
            return null;
        }
        return expandProperty(configurationProperties.getProperty(PREFIX + name));
    }

    /**
     * Gets the configuration property array.
     * <p>
     * Property array is constructed form the list of properties
     * which end with {@code [index]}
     * </p>
     * <pre>
     * daemon.arg[0] = argument 1
     * daemon.arg[1] = argument 2
     * daemon.arg[2] = argument 3
     * </pre>
     * @param name The name of the property array to get.
     *
     * @throws ParseException if the property is wrongly formatted.
     *
     * @return  Configuration property array including any expansion/replacement
     */
    public String[] getPropertyArray(final String name)
        throws ParseException
    {
        final ArrayList<String> list = new ArrayList<String>();
        String    args;

        // Load daemon.arg[0] ... daemon.arg[n] into the String array.
        //
        while ((args = getProperty(name + "[" + list.size() + "]")) != null) {
            list.add(args);
        }
        return list.toArray(EMPTY_STRING_ARRAY);
    }
}

