package com.atlassian.bitbucket.test.rest.repository.sync;

import com.atlassian.bitbucket.test.rest.AbstractRestRequest;
import com.atlassian.bitbucket.test.rest.HasBody;
import com.google.common.collect.ImmutableMap;
import net.sf.json.JSONObject;

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

import static com.google.common.base.Preconditions.checkNotNull;

public class RestSynchronizeRefRequest extends AbstractRestRequest implements HasBody {

    private final RestRefSyncAction action;
    private final JSONObject body;
    private final Map<String, Object> context;
    private final String refId;

    private RestSynchronizeRefRequest(Builder builder) {
        super(builder);

        this.action = builder.action;
        this.context = builder.context.build();
        this.refId = builder.refId;

        body = new JSONObject();
        body.put("refId", refId);
        body.put("action", action);
        if (!context.isEmpty()) {
            body.put("context", JSONObject.fromObject(context));
        }
    }

    @Nonnull
    @Override
    public JSONObject getBody() {
        return body;
    }

    public static class Builder extends AbstractBuilder<Builder, RestSynchronizeRefRequest> {

        private final ImmutableMap.Builder<String, Object> context;
        private final String refId;

        private RestRefSyncAction action;

        public Builder(String refId) {
            this.refId = checkNotBlank(refId, "refId");

            action = RestRefSyncAction.MERGE;
            context = ImmutableMap.builder();
        }

        public Builder(@Nonnull RestSynchronizeRefRequest request) {
            super(request);

            action = request.action;
            context = ImmutableMap.builder();
            context.putAll(request.context);
            refId = request.refId;
        }

        @Nonnull
        public Builder action(@Nonnull RestRefSyncAction value) {
            action = checkNotNull(value, "action");

            return self();
        }

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

        @Nonnull
        public Builder context(@Nonnull String key, @Nonnull Object value) {
            context.put(checkNotBlank(key, "key"), checkNotNull(value, "value"));

            return self();
        }

        @Nonnull
        public Builder context(@Nonnull Map<String, Object> value) {
            context.putAll(value);

            return self();
        }

        @Nonnull
        @Override
        protected Builder self() {
            return this;
        }
    }
}
