package org.apache.maven.shared.filtering;

/*
 * 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.
 */

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

import org.apache.maven.shared.utils.StringUtils;
import org.apache.maven.shared.utils.io.IOUtil;

/**
 * @author <a href="mailto:kenney@neonics.com">Kenney Westerhof</a>
 * @author William Ferguson
 */
public final class PropertyUtils
{
    /**
     * Private empty constructor to prevent instantiation.
     */
    private PropertyUtils()
    {
        // prevent instantiation
    }

    /**
     * Reads a property file, resolving all internal variables, using the supplied base properties.
     * <p>
     * The properties are resolved iteratively, so if the value of property A refers to property B, then after
     * resolution the value of property B will contain the value of property B.
     * </p>
     * 
     * @param propFile The property file to load.
     * @param baseProps Properties containing the initial values to substitute into the properties file.
     * @return Properties object containing the properties in the file with their values fully resolved.
     * @throws IOException if profile does not exist, or cannot be read.
     */
    public static Properties loadPropertyFile( File propFile, Properties baseProps )
        throws IOException
    {
        if ( !propFile.exists() )
        {
            throw new FileNotFoundException( propFile.toString() );
        }

        final Properties fileProps = new Properties();
        final FileInputStream inStream = new FileInputStream( propFile );
        try
        {
            fileProps.load( inStream );
        }
        finally
        {
            IOUtil.close( inStream );
        }

        final Properties combinedProps = new Properties();
        combinedProps.putAll( baseProps == null ? new Properties() : baseProps );
        combinedProps.putAll( fileProps );

        // The algorithm iterates only over the fileProps which is all that is required to resolve
        // the properties defined within the file. This is slightly different to current, however
        // I suspect that this was the actual original intent.
        //
        // The difference is that #loadPropertyFile(File, boolean, boolean) also resolves System properties
        // whose values contain expressions. I believe this is unexpected and is not validated by the test cases,
        // as can be verified by replacing the implementation of #loadPropertyFile(File, boolean, boolean)
        // with the commented variant I have provided that reuses this method.

        for ( Object o : fileProps.keySet() )
        {
            final String k = (String) o;
            final String propValue = getPropertyValue( k, combinedProps );
            fileProps.setProperty( k, propValue );
        }

        return fileProps;
    }

    /**
     * Reads a property file, resolving all internal variables.
     *
     * @param propfile The property file to load
     * @param fail whether to throw an exception when the file cannot be loaded or to return null
     * @param useSystemProps whether to incorporate System.getProperties settings into the returned Properties object.
     * @return the loaded and fully resolved Properties object
     * @throws IOException if profile does not exist, or cannot be read.
     */
    public static Properties loadPropertyFile( File propfile, boolean fail, boolean useSystemProps )
        throws IOException
    {

        final Properties baseProps = new Properties();

        if ( useSystemProps )
        {
            baseProps.putAll( System.getProperties() );
        }

        final Properties resolvedProps = new Properties();
        try
        {
            resolvedProps.putAll( loadPropertyFile( propfile, baseProps ) );
        }
        catch ( FileNotFoundException e )
        {
            if ( fail )
            {
                throw new FileNotFoundException( propfile.toString() );
            }
        }

        if ( useSystemProps )
        {
            resolvedProps.putAll( baseProps );
        }

        return resolvedProps;
    }

    /**
     * Retrieves a property value, replacing values like ${token} using the Properties to look them up. It will leave
     * unresolved properties alone, trying for System properties, and implements reparsing (in the case that the value
     * of a property contains a key), and will not loop endlessly on a pair like test = ${test}.
     *
     * @param k
     * @param p
     * @return The filtered property value.
     */
    private static String getPropertyValue( String k, Properties p )
    {
        // This can also be done using InterpolationFilterReader,
        // but it requires reparsing the file over and over until
        // it doesn't change.

        String v = p.getProperty( k );
        String ret = "";
        int idx, idx2;

        while ( ( idx = v.indexOf( "${" ) ) >= 0 )
        {
            // append prefix to result
            ret += v.substring( 0, idx );

            // strip prefix from original
            v = v.substring( idx + 2 );

            // if no matching } then bail
            if ( ( idx2 = v.indexOf( '}' ) ) < 0 )
            {
                break;
            }

            // strip out the key and resolve it
            // resolve the key/value for the ${statement}
            String nk = v.substring( 0, idx2 );
            v = v.substring( idx2 + 1 );
            String nv = p.getProperty( nk );

            // try global environment..
            if ( nv == null && !StringUtils.isEmpty( nk ) )
            {
                nv = System.getProperty( nk );
            }

            // if the key cannot be resolved,
            // leave it alone ( and don't parse again )
            // else prefix the original string with the
            // resolved property ( so it can be parsed further )
            // taking recursion into account.
            if ( nv == null || nv.equals( k ) || k.equals( nk ) )
            {
                ret += "${" + nk + "}";
            }
            else
            {
                v = nv + v;
            }
        }
        return ret + v;
    }
}
