package com.atlassian.stash.internal.config;

import com.google.common.annotations.VisibleForTesting;
import org.joda.time.format.ISODateTimeFormat;

import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.Writer;
import java.util.Set;

import static java.util.Objects.requireNonNull;

/**
 * Removes properties and replaces each of them with a commented line.
 *
 * @since 3.8
 */
public class RemovePropertiesAmendment extends AbstractConfigurationAmendment {

    protected final Set<String> properties;

    public RemovePropertiesAmendment(@Nonnull Clock clock, @Nonnull Set<String> properties) {
        super(clock);

        this.properties = requireNonNull(properties, "properties");
    }

    @VisibleForTesting
    public static String formatComment(@Nonnull String line, @Nonnull Clock clock) {
        return String.format("# %s removed by unattended setup on %s", getPropertyKey(line),
                ISODateTimeFormat.dateTime().print(clock.now()));
    }

    /**
     * A line is amendable if a property key can be found and it is also present in {@link #properties}
     *
     * @param line The line to test
     * @return {@code true} if the line can be amended. {@code false} otherwise.
     */
    @Override
    public boolean isAmendable(@Nonnull String line) {
        return isAmendableProperty(line);
    }

    /**
     * Replace the line with a comment letting users know what we've changed.
     *
     * @param line   line being amended.
     * @param writer where the amendment must be written
     * @throws IOException If there are I/O problems writing to the writer.
     */
    @Override
    public void amend(@Nonnull Writer writer, @Nonnull String line) throws IOException {
        writeLine(writer, formatComment(line, getClock()));
    }

    protected boolean isAmendableProperty(@Nonnull String line) {
        return properties.contains(getPropertyKey(line));
    }
}