package org.apache.maven.shared.release.config;

/*
 * 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.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;

import org.apache.maven.model.Scm;
import org.apache.maven.shared.release.scm.IdentifiedScm;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.IOUtil;
import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
import org.sonatype.plexus.components.cipher.PlexusCipherException;
import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException;
import org.sonatype.plexus.components.sec.dispatcher.SecUtil;
import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;

/**
 * Read and write release configuration and state from a properties file.
 *
 * @author <a href="mailto:brett@apache.org">Brett Porter</a>
 * @plexus.component role="org.apache.maven.shared.release.config.ReleaseDescriptorStore" role-hint="properties"
 */
public class PropertiesReleaseDescriptorStore
    extends AbstractLogEnabled
    implements ReleaseDescriptorStore
{

    /**
     * When this plugin requires Maven 3.0 as minimum, this component can be removed and o.a.m.s.c.SettingsDecrypter be
     * used instead.
     *
     * @plexus.requirement role="org.sonatype.plexus.components.sec.dispatcher.SecDispatcher" role-hint="mng-4384"
     */

    private DefaultSecDispatcher secDispatcher;

    public ReleaseDescriptor read( ReleaseDescriptor mergeDescriptor )
        throws ReleaseDescriptorStoreException
    {
        return read( mergeDescriptor, getDefaultReleasePropertiesFile( mergeDescriptor ) );
    }

    public ReleaseDescriptor read( File file )
        throws ReleaseDescriptorStoreException
    {
        return read( null, file );
    }

    public ReleaseDescriptor read( ReleaseDescriptor mergeDescriptor, File file )
        throws ReleaseDescriptorStoreException
    {
        Properties properties = new Properties();

        InputStream inStream = null;
        try
        {
            inStream = new FileInputStream( file );

            properties.load( inStream );
        }
        catch ( FileNotFoundException e )
        {
            getLogger().debug( file.getName() + " not found - using empty properties" );
        }
        catch ( IOException e )
        {
            throw new ReleaseDescriptorStoreException(
                "Error reading properties file '" + file.getName() + "': " + e.getMessage(), e );
        }
        finally
        {
            IOUtil.close( inStream );
        }

        ReleaseDescriptor releaseDescriptor = ReleaseUtils.copyPropertiesToReleaseDescriptor( properties );

        if ( mergeDescriptor != null )
        {
            releaseDescriptor = ReleaseUtils.merge( releaseDescriptor, mergeDescriptor );
        }

        return releaseDescriptor;
    }

    public void write( ReleaseDescriptor config )
        throws ReleaseDescriptorStoreException
    {
        write( config, getDefaultReleasePropertiesFile( config ) );
    }

    public void delete( ReleaseDescriptor config )
    {
        File file = getDefaultReleasePropertiesFile( config );
        if ( file.exists() )
        {
            file.delete();
        }
    }

    public void write( ReleaseDescriptor config, File file )
        throws ReleaseDescriptorStoreException
    {
        Properties properties = new Properties();
        properties.setProperty( "completedPhase", config.getCompletedPhase() );
        if ( config.isCommitByProject() ) //default is false
        {
            properties.setProperty( "commitByProject", "true" );
        }
        properties.setProperty( "scm.url", config.getScmSourceUrl() );
        if ( config.getScmId() != null )
        {
            properties.setProperty( "scm.id", config.getScmId() );
        }
        if ( config.getScmUsername() != null )
        {
            properties.setProperty( "scm.username", config.getScmUsername() );
        }
        if ( config.getScmPassword() != null )
        {
            String password = config.getScmPassword();
            try
            {
                password = encryptAndDecorate( password );
            }
            catch ( IllegalStateException e )
            {
                getLogger().debug( e.getMessage() );
            }
            catch ( SecDispatcherException e )
            {
                getLogger().debug( e.getMessage() );
            }
            catch ( PlexusCipherException e )
            {
                getLogger().debug( e.getMessage() );
            }
            properties.setProperty( "scm.password", password );
        }
        if ( config.getScmPrivateKey() != null )
        {
            properties.setProperty( "scm.privateKey", config.getScmPrivateKey() );
        }
        if ( config.getScmPrivateKeyPassPhrase() != null )
        {
            String passPhrase = config.getScmPrivateKeyPassPhrase();
            try
            {
                passPhrase = encryptAndDecorate( passPhrase );
            }
            catch ( IllegalStateException e )
            {
                getLogger().debug( e.getMessage() );
            }
            catch ( SecDispatcherException e )
            {
                getLogger().debug( e.getMessage() );
            }
            catch ( PlexusCipherException e )
            {
                getLogger().debug( e.getMessage() );
            }
            properties.setProperty( "scm.passphrase", passPhrase  );
        }
        if ( config.getScmTagBase() != null )
        {
            properties.setProperty( "scm.tagBase", config.getScmTagBase() );
        }
        if ( config.getScmBranchBase() != null )
        {
            properties.setProperty( "scm.branchBase", config.getScmBranchBase() );
        }
        if ( config.getScmReleaseLabel() != null )
        {
            properties.setProperty( "scm.tag", config.getScmReleaseLabel() );
        }
        if ( config.getScmTagNameFormat() != null )
        {
            properties.setProperty( "scm.tagNameFormat", config.getScmTagNameFormat() );
        }
        if ( config.getScmCommentPrefix() != null )
        {
            properties.setProperty( "scm.commentPrefix", config.getScmCommentPrefix() );
        }
        if ( config.getAdditionalArguments() != null )
        {
            properties.setProperty( "exec.additionalArguments", config.getAdditionalArguments() );
        }
        if ( config.getPomFileName() != null )
        {
            properties.setProperty( "exec.pomFileName", config.getPomFileName() );
        }
        if ( config.getPreparationGoals() != null )
        {
            properties.setProperty( "preparationGoals", config.getPreparationGoals() );
        }
        if ( config.getCompletionGoals() != null )
        {
            properties.setProperty( "completionGoals", config.getCompletionGoals() );
        }
        if ( config.getProjectVersionPolicyId() != null )
        {
            properties.setProperty( "projectVersionPolicyId", config.getProjectVersionPolicyId() );
        }

        properties.setProperty( "exec.snapshotReleasePluginAllowed",
                                Boolean.toString( config.isSnapshotReleasePluginAllowed() ) );

        properties.setProperty( "remoteTagging", Boolean.toString( config.isRemoteTagging() ) );

        properties.setProperty( "pushChanges", Boolean.toString( config.isPushChanges() ) );

        // others boolean properties are not written to the properties file because the value from the caller is always
        // used

        for ( Iterator<?> i = config.getReleaseVersions().entrySet().iterator(); i.hasNext(); )
        {
            Map.Entry<?, ?> entry = (Map.Entry<?, ?>) i.next();
            properties.setProperty( "project.rel." + entry.getKey(), (String) entry.getValue() );
        }

        for ( Iterator<?> i = config.getDevelopmentVersions().entrySet().iterator(); i.hasNext(); )
        {
            Map.Entry<?, ?> entry = (Map.Entry<?, ?>) i.next();
            properties.setProperty( "project.dev." + entry.getKey(), (String) entry.getValue() );
        }

        for ( Iterator<?> i = config.getOriginalScmInfo().entrySet().iterator(); i.hasNext(); )
        {
            Map.Entry<?, ?> entry = (Map.Entry<?, ?>) i.next();
            Scm scm = (Scm) entry.getValue();
            String prefix = "project.scm." + entry.getKey();
            if ( scm != null )
            {
                if ( scm.getConnection() != null )
                {
                    properties.setProperty( prefix + ".connection", scm.getConnection() );
                }
                if ( scm.getDeveloperConnection() != null )
                {
                    properties.setProperty( prefix + ".developerConnection", scm.getDeveloperConnection() );
                }
                if ( scm.getUrl() != null )
                {
                    properties.setProperty( prefix + ".url", scm.getUrl() );
                }
                if ( scm.getTag() != null )
                {
                    properties.setProperty( prefix + ".tag", scm.getTag() );
                }
                if ( scm instanceof IdentifiedScm )
                {
                    IdentifiedScm identifiedScm = (IdentifiedScm) scm;
                    if ( identifiedScm.getId() != null )
                    {
                        properties.setProperty( prefix + ".id", identifiedScm.getId() );
                    }
                }
            }
            else
            {
                properties.setProperty( prefix + ".empty", "true" );
            }
        }

        if ( ( config.getResolvedSnapshotDependencies() != null )
            && ( config.getResolvedSnapshotDependencies().size() > 0 ) )
        {
            processResolvedDependencies( properties, config.getResolvedSnapshotDependencies() );
        }

        OutputStream outStream = null;
        //noinspection OverlyBroadCatchBlock
        try
        {
            outStream = new FileOutputStream( file );

            properties.store( outStream, "release configuration" );
        }
        catch ( IOException e )
        {
            throw new ReleaseDescriptorStoreException(
                "Error writing properties file '" + file.getName() + "': " + e.getMessage(), e );
        }
        finally
        {
            IOUtil.close( outStream );
        }

    }

    private void processResolvedDependencies( Properties prop, Map<?, ?> resolvedDependencies )
    {
        Set<?> entries = resolvedDependencies.entrySet();
        Iterator<?> iterator = entries.iterator();
        Entry<?, ?> currentEntry;

        while ( iterator.hasNext() )
        {
            currentEntry = (Entry<?, ?>) iterator.next();

            Map<?, ?> versionMap = (Map<?, ?>) currentEntry.getValue();

            prop.setProperty( "dependency." + currentEntry.getKey() + ".release",
                              (String) versionMap.get( ReleaseDescriptor.RELEASE_KEY ) );
            prop.setProperty( "dependency." + currentEntry.getKey() + ".development",
                              (String) versionMap.get( ReleaseDescriptor.DEVELOPMENT_KEY ) );
        }
    }

    private static File getDefaultReleasePropertiesFile( ReleaseDescriptor mergeDescriptor )
    {
        return new File( mergeDescriptor.getWorkingDirectory(), "release.properties" );
    }

    // From org.apache.maven.cli.MavenCli.encryption(CliRequest)
    private String encryptAndDecorate( String passwd )
        throws IllegalStateException, SecDispatcherException, PlexusCipherException
    {
        String configurationFile = secDispatcher.getConfigurationFile();

        if ( configurationFile.startsWith( "~" ) )
        {
            configurationFile = System.getProperty( "user.home" ) + configurationFile.substring( 1 );
        }

        String file = System.getProperty( DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION, configurationFile );

        String master = null;

        SettingsSecurity sec = SecUtil.read( file, true );
        if ( sec != null )
        {
            master = sec.getMaster();
        }

        if ( master == null )
        {
            throw new IllegalStateException( "Master password is not set in the setting security file: " + file );
        }

        DefaultPlexusCipher cipher = new DefaultPlexusCipher();
        String masterPasswd = cipher.decryptDecorated( master, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION );
        return cipher.encryptAndDecorate( passwd, masterPasswd );
    }

}
