package org.apache.maven.settings;

/*
 * 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 org.apache.maven.settings.io.xpp3.SettingsXpp3Reader;
import org.codehaus.plexus.interpolation.EnvarBasedValueSource;
import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.List;

/**
 * @author jdcasey
 * @version $Id$
 */
public class DefaultMavenSettingsBuilder
    extends AbstractLogEnabled
    implements MavenSettingsBuilder, Initializable
{
    public static final String userHome = System.getProperty( "user.home" );

    /**
     * @configuration
     */
    private String userSettingsPath;

    /**
     * @configuration
     */
    private String globalSettingsPath;

    private File userSettingsFile;

    private File globalSettingsFile;

    private Settings loadedSettings;

    // ----------------------------------------------------------------------
    // Component Lifecycle
    // ----------------------------------------------------------------------

    public void initialize()
    {
        userSettingsFile =
            getFile( userSettingsPath, "user.home", MavenSettingsBuilder.ALT_USER_SETTINGS_XML_LOCATION );

        globalSettingsFile =
            getFile( globalSettingsPath, "maven.home", MavenSettingsBuilder.ALT_GLOBAL_SETTINGS_XML_LOCATION );

        getLogger().debug(
            "Building Maven global-level settings from: '" + globalSettingsFile.getAbsolutePath() + "'" );
        getLogger().debug( "Building Maven user-level settings from: '" + userSettingsFile.getAbsolutePath() + "'" );
    }

    // ----------------------------------------------------------------------
    // MavenProfilesBuilder Implementation
    // ----------------------------------------------------------------------

    private Settings readSettings( File settingsFile )
        throws IOException, XmlPullParserException
    {
        Settings settings = null;

        if ( settingsFile != null && settingsFile.exists() && settingsFile.isFile() )
        {
            Reader reader = null;
            try
            {
                reader = ReaderFactory.newXmlReader( settingsFile );
                StringWriter sWriter = new StringWriter();

                IOUtil.copy( reader, sWriter );

                String rawInput = sWriter.toString();

                try
                {
                    RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
                    interpolator.addValueSource( new EnvarBasedValueSource() );

                    rawInput = interpolator.interpolate( rawInput, "settings" );
                }
                catch ( Exception e )
                {
                    getLogger().warn(
                        "Failed to initialize environment variable resolver. Skipping environment substitution in settings." );
                    getLogger().debug( "Failed to initialize envar resolver. Skipping resolution.", e );
                }

                StringReader sReader = new StringReader( rawInput );

                SettingsXpp3Reader modelReader = new SettingsXpp3Reader();

                settings = modelReader.read( sReader, true );

                RuntimeInfo rtInfo = new RuntimeInfo( settings );

                rtInfo.setFile( settingsFile );

                settings.setRuntimeInfo( rtInfo );
            }
            finally
            {
                IOUtil.close( reader );
            }
        }

        return settings;
    }

    public Settings buildSettings()
        throws IOException, XmlPullParserException
    {
        return buildSettings( userSettingsFile );
    }

    public Settings buildSettings( boolean useCachedSettings )
        throws IOException, XmlPullParserException
    {
        return buildSettings( userSettingsFile, useCachedSettings );
    }

    public Settings buildSettings( File userSettingsFile )
        throws IOException, XmlPullParserException
    {
        return buildSettings( userSettingsFile, true );
    }

    public Settings buildSettings( File userSettingsFile, boolean useCachedSettings )
        throws IOException, XmlPullParserException
    {
        if ( !useCachedSettings || loadedSettings == null )
        {
            Settings globalSettings = readSettings( globalSettingsFile );
            Settings userSettings = readSettings( userSettingsFile );

            if ( globalSettings == null )
            {
                globalSettings = new Settings();
            }

            if ( userSettings == null )
            {
                userSettings = new Settings();
                userSettings.setRuntimeInfo( new RuntimeInfo( userSettings ) );
            }

            SettingsUtils.merge( userSettings, globalSettings, TrackableBase.GLOBAL_LEVEL );

            activateDefaultProfiles( userSettings );

            setLocalRepository( userSettings );

            loadedSettings = userSettings;
        }

        return loadedSettings;
    }

    private void activateDefaultProfiles( Settings settings )
    {
        List<String> activeProfiles = settings.getActiveProfiles();

        for ( Profile profile : settings.getProfiles() )
        {
            if ( profile.getActivation() != null && profile.getActivation().isActiveByDefault()
                && !activeProfiles.contains( profile.getId() ) )
            {
                settings.addActiveProfile( profile.getId() );
            }
        }
    }

    private void setLocalRepository( Settings userSettings )
    {
        // try using the local repository specified on the command line...
        String localRepository = System.getProperty( MavenSettingsBuilder.ALT_LOCAL_REPOSITORY_LOCATION );

        // otherwise, use the one in settings.xml
        if ( localRepository == null || localRepository.length() < 1 )
        {
            localRepository = userSettings.getLocalRepository();
        }

        // if all of the above are missing, default to ~/.m2/repository.
        if ( localRepository == null || localRepository.length() < 1 )
        {
            File mavenUserConfigurationDirectory = new File( userHome, ".m2" );
            if ( !mavenUserConfigurationDirectory.exists() )
            {
                if ( !mavenUserConfigurationDirectory.mkdirs() )
                {
                    //throw a configuration exception
                }
            }

            localRepository = new File( mavenUserConfigurationDirectory, "repository" ).getAbsolutePath();
        }

        // for the special case of a drive-relative Windows path, make sure it's absolute to save plugins from trouble
        File file = new File( localRepository );
        if ( !file.isAbsolute() && file.getPath().startsWith( File.separator ) )
        {
            localRepository = file.getAbsolutePath();
        }

        userSettings.setLocalRepository( localRepository );
    }

    private File getFile( String pathPattern, String basedirSysProp, String altLocationSysProp )
    {
        // -------------------------------------------------------------------------------------
        // Alright, here's the justification for all the regexp wizardry below...
        //
        // Continuum and other server-like apps may need to locate the user-level and
        // global-level settings somewhere other than ${user.home} and ${maven.home},
        // respectively. Using a simple replacement of these patterns will allow them
        // to specify the absolute path to these files in a customized components.xml
        // file. Ideally, we'd do full pattern-evaluation against the sysprops, but this
        // is a first step. There are several replacements below, in order to normalize
        // the path character before we operate on the string as a regex input, and
        // in order to avoid surprises with the File construction...
        // -------------------------------------------------------------------------------------

        String path = System.getProperty( altLocationSysProp );

        if ( StringUtils.isEmpty( path ) )
        {
            // TODO: This replacing shouldn't be necessary as user.home should be in the
            // context of the container and thus the value would be interpolated by Plexus
            String basedir = System.getProperty( basedirSysProp );
            if ( basedir == null )
            {
                basedir = System.getProperty( "user.dir" );
            }

            basedir = basedir.replaceAll( "\\\\", "/" );
            basedir = basedir.replaceAll( "\\$", "\\\\\\$" );

            path = pathPattern.replaceAll( "\\$\\{" + basedirSysProp + "\\}", basedir );
            path = path.replaceAll( "\\\\", "/" );
            // ---------------------------------------------------------------------------------
            // I'm not sure if this last regexp was really intended to disallow the usage of
            // network paths as user.home directory. Unfortunately it did. I removed it and
            // have not detected any problems yet.
            // ---------------------------------------------------------------------------------
            // path = path.replaceAll( "//", "/" );

            return new File( path ).getAbsoluteFile();
        }
        else
        {
            return new File( path ).getAbsoluteFile();
        }
    }

}
