package com.atlassian.stash.internal.scm.git.ui;

import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.ui.ContextualFormFragment;
import com.atlassian.bitbucket.ui.ValidationErrors;
import com.atlassian.bitbucket.view.TemplateRenderingException;
import com.atlassian.soy.renderer.SoyException;
import com.atlassian.soy.renderer.SoyTemplateRenderer;
import com.atlassian.stash.internal.scm.git.transcode.TranscodeService;

import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;

import static java.util.Objects.requireNonNull;

/**
 * @since 3.1
 */
public class TranscodeDiffsFormFragment implements ContextualFormFragment {

    private static final String FRAGMENT_TEMPLATE = "bitbucket.internal.feature.scmGit.transcode.enable";
    private static final String RESOURCE_KEY = "com.atlassian.bitbucket.server.bitbucket-git:transcode-settings";
    private static final String FIELD_KEY = "git-enable-transcoding";
    private static final String SOY_PARAM_ENABLED = "enabled";

    private final SoyTemplateRenderer soyTemplateRenderer;
    private final TranscodeService transcodeService;

    public TranscodeDiffsFormFragment(SoyTemplateRenderer soyTemplateRenderer, TranscodeService transcodeService) {
        this.soyTemplateRenderer = soyTemplateRenderer;
        this.transcodeService = transcodeService;
    }

    @Override
    public void doError(@Nonnull Appendable appendable, @Nonnull Map<String, String[]> requestParams,
                        @Nonnull Map<String, Collection<String>> fieldErrors, @Nonnull Map<String, Object> context) {
        requireNonNull(appendable, "appendable");
        requireNonNull(requestParams, "requestParams");
        requireNonNull(context, "context");

        context.put(SOY_PARAM_ENABLED, isCheckBoxEnabled(requestParams));
        renderView(appendable, context);
    }

    @Override
    public void doView(@Nonnull Appendable appendable, @Nonnull Map<String, Object> context) throws IOException {
        requireNonNull(appendable, "appendable");
        requireNonNull(context, "context");

        Repository repository = (Repository) context.get("repository");
        context.put(SOY_PARAM_ENABLED, transcodeService.isEnabled(repository));
        renderView(appendable, context);
    }

    @Override
    public void execute(@Nonnull Map<String, String[]> requestParams, @Nonnull Map<String, Object> context) {
        requireNonNull(requestParams, "requestParams");
        requireNonNull(context, "context");

        Repository repository = (Repository) context.get("repository");
        //Any exception thrown while toggling transcoding is considered unrecoverable here
        transcodeService.setEnabled(repository, isCheckBoxEnabled(requestParams));
    }

    @Override
    public void validate(@Nonnull Map<String, String[]> requestParams, @Nonnull ValidationErrors errors,
                         @Nonnull Map<String, Object> context) {
        //Simple checkbox; no validation necessary
    }

    /**
     * Gets the status of the "enabled" checkbox
     */
    private boolean isCheckBoxEnabled(Map<String, String[]> requestParams) {
        String[] values = requestParams.get(FIELD_KEY);
        return values != null && values.length == 1 && values[0].equalsIgnoreCase("on");
    }

    private void renderView(Appendable appendable, Map<String, Object> context) {
        try {
            soyTemplateRenderer.render(appendable, RESOURCE_KEY, FRAGMENT_TEMPLATE, context);
        } catch (SoyException e) {
            throw new TemplateRenderingException("Failed to render " + FRAGMENT_TEMPLATE, e);
        }
    }
}
