/*
 * 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.maven.shared.release.config;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

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.Map;
import java.util.Properties;

import org.apache.maven.model.Scm;
import org.apache.maven.shared.release.config.ReleaseDescriptorBuilder.BuilderReleaseDescriptor;
import org.apache.maven.shared.release.scm.IdentifiedScm;
import org.apache.maven.shared.release.util.MavenCrypto;
import org.apache.maven.shared.release.util.MavenCrypto.MavenCryptoException;
import org.codehaus.plexus.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static java.util.Objects.requireNonNull;

/**
 * Read and write release configuration and state from a properties file.
 *
 * @author <a href="mailto:brett@apache.org">Brett Porter</a>
 */
@Singleton
@Named("properties")
public class PropertiesReleaseDescriptorStore implements ReleaseDescriptorStore {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    private final MavenCrypto mavenCrypto;

    @Inject
    public PropertiesReleaseDescriptorStore(MavenCrypto mavenCrypto) {
        this.mavenCrypto = requireNonNull(mavenCrypto);
    }

    @Override
    public ReleaseDescriptorBuilder read(ReleaseDescriptorBuilder mergeDescriptor)
            throws ReleaseDescriptorStoreException {
        return read(mergeDescriptor, getDefaultReleasePropertiesFile(mergeDescriptor.build()));
    }

    /**
     * <p>read.</p>
     *
     * @param file a {@link java.io.File} object
     * @return a {@link org.apache.maven.shared.release.config.ReleaseDescriptorBuilder} object
     * @throws org.apache.maven.shared.release.config.ReleaseDescriptorStoreException if any.
     */
    public ReleaseDescriptorBuilder read(File file) throws ReleaseDescriptorStoreException {
        return read(null, file);
    }

    /**
     * <p>read.</p>
     *
     * @param mergeDescriptor a {@link org.apache.maven.shared.release.config.ReleaseDescriptorBuilder} object
     * @param file            a {@link java.io.File} object
     * @return a {@link org.apache.maven.shared.release.config.ReleaseDescriptorBuilder} object
     * @throws org.apache.maven.shared.release.config.ReleaseDescriptorStoreException if any.
     */
    public ReleaseDescriptorBuilder read(ReleaseDescriptorBuilder mergeDescriptor, File file)
            throws ReleaseDescriptorStoreException {
        Properties properties = new Properties();

        try (InputStream inStream = new FileInputStream(file)) {
            properties.load(inStream);
        } catch (FileNotFoundException e) {
            logger.debug(file.getName() + " not found - using empty properties");
        } catch (IOException e) {
            throw new ReleaseDescriptorStoreException(
                    "Error reading properties file '" + file.getName() + "': " + e.getMessage(), e);
        }

        try {
            mavenCrypto.decryptProperties(properties);
        } catch (MavenCryptoException e) {
            logger.debug(e.getMessage());
        }

        ReleaseDescriptorBuilder builder;
        if (mergeDescriptor != null) {
            builder = mergeDescriptor;
        } else {
            builder = new ReleaseDescriptorBuilder();
        }

        ReleaseUtils.copyPropertiesToReleaseDescriptor(properties, builder);

        return builder;
    }

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

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

    /**
     * <p>write.</p>
     *
     * @param config a {@link org.apache.maven.shared.release.config.ReleaseDescriptorBuilder.BuilderReleaseDescriptor}
     *               object
     * @param file   a {@link java.io.File} object
     * @throws org.apache.maven.shared.release.config.ReleaseDescriptorStoreException if any.
     */
    public void write(BuilderReleaseDescriptor 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 = mavenCrypto.encryptAndDecorate(password);
            } catch (MavenCryptoException e) {
                logger.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 = mavenCrypto.encryptAndDecorate(passPhrase);
            } catch (MavenCryptoException e) {
                logger.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.getScmDevelopmentCommitComment() != null) {
            properties.setProperty("scm.developmentCommitComment", config.getScmDevelopmentCommitComment());
        }
        if (config.getScmReleaseCommitComment() != null) {
            properties.setProperty("scm.releaseCommitComment", config.getScmReleaseCommitComment());
        }
        if (config.getScmBranchCommitComment() != null) {
            properties.setProperty("scm.branchCommitComment", config.getScmBranchCommitComment());
        }
        if (config.getScmRollbackCommitComment() != null) {
            properties.setProperty("scm.rollbackCommitComment", config.getScmRollbackCommitComment());
        }
        if (config.getAdditionalArguments() != null) {
            properties.setProperty("exec.additionalArguments", config.getAdditionalArguments());
        }
        if (config.getPomFileName() != null) {
            properties.setProperty("exec.pomFileName", config.getPomFileName());
        }
        if (!config.getActivateProfiles().isEmpty()) {
            properties.setProperty(
                    "exec.activateProfiles",
                    StringUtils.join(config.getActivateProfiles().iterator(), ","));
        }
        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());
        }
        if (config.getProjectVersionPolicyConfig() != null) {
            properties.setProperty(
                    "projectVersionPolicyConfig",
                    config.getProjectVersionPolicyConfig().toString());
        }
        if (config.getProjectNamingPolicyId() != null) {
            properties.setProperty("projectNamingPolicyId", config.getProjectNamingPolicyId());
        }
        if (config.getReleaseStrategyId() != null) {
            properties.setProperty("releaseStrategyId", config.getReleaseStrategyId());
        }

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

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

        properties.setProperty("pinExternals", Boolean.toString(config.isPinExternals()));

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

        if (config.getWorkItem() != null) {
            properties.setProperty("workItem", config.getWorkItem());
        }

        if (config.getAutoResolveSnapshots() != null) {
            properties.setProperty("autoResolveSnapshots", config.getAutoResolveSnapshots());
        }

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

        for (Map.Entry<String, ReleaseStageVersions> entry :
                config.getProjectVersions().entrySet()) {
            if (entry.getValue().getRelease() != null) {
                properties.setProperty(
                        "project.rel." + entry.getKey(), entry.getValue().getRelease());
            }
            if (entry.getValue().getDevelopment() != null) {
                properties.setProperty(
                        "project.dev." + entry.getKey(), entry.getValue().getDevelopment());
            }
        }

        for (Map.Entry<String, Scm> entry : config.getOriginalScmInfo().entrySet()) {
            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());
        }

        try (OutputStream outStream = new FileOutputStream(file)) {
            properties.store(outStream, "release configuration");
        } catch (IOException e) {
            throw new ReleaseDescriptorStoreException(
                    "Error writing properties file '" + file.getName() + "': " + e.getMessage(), e);
        }
    }

    private void processResolvedDependencies(Properties prop, Map<String, ReleaseStageVersions> resolvedDependencies) {
        for (Map.Entry<String, ReleaseStageVersions> currentEntry : resolvedDependencies.entrySet()) {
            ReleaseStageVersions versionMap = currentEntry.getValue();

            prop.setProperty("dependency." + currentEntry.getKey() + ".release", versionMap.getRelease());
            prop.setProperty("dependency." + currentEntry.getKey() + ".development", versionMap.getDevelopment());
        }
    }

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