package com.atlassian.bitbucket.mesh.git.hook;

import com.atlassian.bitbucket.mesh.util.BuilderSupport;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

import javax.annotation.Nonnull;
import java.util.List;
import java.util.Map;

import static com.atlassian.bitbucket.mesh.git.GitConstants.ENV_BB_GIT_COMMAND;
import static java.util.Objects.requireNonNull;

public class GitHookRequest implements HookRequest {

    private final List<String> arguments;
    private final Map<String, String> environment;
    private final String hookName;
    private final HookStdin stdin;

    private GitHookRequest(Builder builder) {
        arguments = builder.arguments.build();
        environment = builder.environment.build();
        stdin = builder.stdin;
        hookName = builder.hookName;
    }

    @Override
    public String getCommand() {
        return environment.get(ENV_BB_GIT_COMMAND);
    }

    @Nonnull
    @Override
    public List<String> getArguments() {
        return arguments;
    }

    @Nonnull
    @Override
    public Map<String, String> getEnvironment() {
        return environment;
    }

    @Override
    public String getHookName() {
        return hookName;
    }

    @Nonnull
    @Override
    public HookStdin getStdin() {
        return stdin;
    }

    @Override
    public String toString() {
        return hookName;
    }

    public static class Builder extends BuilderSupport {

        private final ImmutableList.Builder<String> arguments;
        private final ImmutableMap.Builder<String, String> environment;
        private final String hookName;

        private HookStdin stdin;

        public Builder(@Nonnull String hookName) {
            this.hookName = requireNonBlank(hookName, "hookName");

            arguments = ImmutableList.builder();
            environment = ImmutableMap.builder();
            stdin = EmptyHookStdin.INSTANCE;
        }

        @Nonnull
        public Builder argument(@Nonnull String value) {
            arguments.add(requireNonNull(value, "value"));

            return this;
        }

        @Nonnull
        public GitHookRequest build() {
            return new GitHookRequest(this);
        }

        @Nonnull
        public Builder environment(@Nonnull String key, @Nonnull String value) {
            environment.put(requireNonBlank(key, "key"), requireNonNull(value, "value"));

            return this;
        }

        @Nonnull
        public Builder stdin(@Nonnull HookStdin value) {
            stdin = requireNonNull(value, "stdin");

            return this;
        }

        @Nonnull
        public Builder stdin(@Nonnull String value) {
            stdin = ByteStringHookStdin.of(requireNonNull(value, "stdin"));

            return this;
        }
    }
}
