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

import com.atlassian.bitbucket.mesh.rpc.v1.RpcSubmodule;
import com.atlassian.bitbucket.mesh.util.BuilderSupport;
import com.google.protobuf.ByteString;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import static com.atlassian.bitbucket.mesh.rpc.util.ByteStringUtils.nullToEmpty;
import static java.util.Objects.requireNonNull;

public class Submodule {

    private final boolean active;
    private final String branch;
    private final String contentId;
    private final String path;
    private final String url;

    Submodule(@Nonnull String path, @Nonnull String contentId, @Nonnull SubmoduleConfig config) {
        this.contentId = requireNonNull(contentId, "contentId");
        this.path = requireNonNull(path, "path"); //config.getPath() is qualified; this may not be

        active = requireNonNull(config, "config").isActive();
        branch = config.getBranch();
        url = config.getUrl();
    }

    private Submodule(Builder builder) {
        active = builder.active == null ? builder.url != null : builder.active;
        branch = builder.branch;
        contentId = builder.contentId;
        path = builder.path;
        url = builder.url;
    }

    @Nullable
    public String getBranch() {
        return branch;
    }

    @Nonnull
    public String getContentId() {
        return contentId;
    }

    @Nonnull
    public String getPath() {
        return path;
    }

    @Nonnull
    public String getUrl() {
        return url;
    }

    public boolean isActive() {
        return active;
    }

    @Nonnull
    public RpcSubmodule toSubmodule() {
        return RpcSubmodule.newBuilder()
                .setActive(active)
                .setBranch(nullToEmpty(branch))
                .setContentId(contentId)
                .setPath(ByteString.copyFromUtf8(path))
                .setUrl(url)
                .build();
    }

    public static class Builder extends BuilderSupport {

        private final String contentId;
        private final String path;

        private Boolean active;
        private String branch;
        private String url;

        public Builder(@Nonnull String path, @Nonnull String contentId) {
            this.contentId = requireNonBlank(contentId, "contentId");
            this.path = requireNonBlank(path, "path");
        }

        @Nonnull
        public Builder active(boolean value) {
            active = value;

            return this;
        }

        @Nonnull
        public Builder branch(@Nullable String value) {
            branch = value;

            return this;
        }

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

        @Nonnull
        public Builder url(@Nonnull String value) {
            url = requireNonBlank(value, "url");
            if (active == null) {
                //If a URL is present, active defaults to true unless it's explicitly set to false.
                //So if a URL is set and active has not yet been set, we default it
                active = Boolean.TRUE;
            }

            return this;
        }
    }
}
