package com.atlassian.stash.internal.repository.sync.ui;

import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.repository.sync.RefSyncService;
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 javax.annotation.Nonnull;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;

import static com.atlassian.stash.internal.repository.sync.ui.RefSyncResources.RESOURCE_KEY;
import static com.atlassian.stash.internal.repository.sync.ui.RefSyncResources.TEMPLATE_ENABLE;
import static java.util.Objects.requireNonNull;

/**
 * @since 2.6
 */
public class EnableRefSyncingFormFragment implements ContextualFormFragment {

    private static final String FIELD_KEY = "enable-ref-syncing";
    private static final boolean REF_SYNC_DEFAULT = true;
    private static final String SOY_PARAM_ENABLED = "enabled";

    private final SoyTemplateRenderer soyTemplateRenderer;
    private final RefSyncService syncService;

    public EnableRefSyncingFormFragment(SoyTemplateRenderer soyTemplateRenderer, RefSyncService syncService) {
        this.soyTemplateRenderer = soyTemplateRenderer;
        this.syncService = syncService;
    }

    @Override
    public void doError(@Nonnull Appendable appendable, @Nonnull Map<String, String[]> requestParams,
                        @Nonnull Map<String, Collection<String>> fieldErrors, @Nonnull Map<String, Object> context)
            throws IOException {
        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");

        context.put(SOY_PARAM_ENABLED, REF_SYNC_DEFAULT);
        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("fork");
        syncService.setEnabled(repository, isCheckBoxEnabled(requestParams));
    }

    @Override
    public void validate(@Nonnull Map<String, String[]> requestParams, @Nonnull ValidationErrors errors,
                         @Nonnull Map<String, Object> context) {
        // Validation is not necessary since ref syncing will be available when forking
    }

    /**
     * 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, TEMPLATE_ENABLE, context);
        } catch (SoyException e) {
            throw new TemplateRenderingException("Failed to render " + TEMPLATE_ENABLE, e);
        }
    }
}
