package com.atlassian.bitbucket.content;

import com.google.common.base.Objects;

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

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

public class SimpleSubmodule extends Submodule {

    private final String contentId;
    private final Path path;
    private final String url;
    private final String repositoryUrl;
    private final String browseUrl;

    private SimpleSubmodule(Builder builder) {
        browseUrl = builder.browseUrl;
        contentId = builder.contentId;
        path = builder.path;
        repositoryUrl = builder.repositoryUrl;
        url = builder.url;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o instanceof SimpleSubmodule) {
            SimpleSubmodule f = (SimpleSubmodule) o;

            return getPath().equals(f.getPath()) &&
                    Objects.equal(getContentId(), f.getContentId());
        }
        return false;
    }

    @Override
    public String getBrowseUrl() {
        return browseUrl;
    }

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

    @Nonnull
    @Override
    public Path getPath() {
        return path;
    }

    @Override
    public String getRepositoryUrl() {
        return repositoryUrl;
    }

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

    @Override
    public int hashCode() {
        return Objects.hashCode(getPath(), getContentId());
    }

    @Override
    public String toString() {
        return "SimpleSubmodule{" +
                "path='" + path + '\'' +
                ", contentId='" + contentId + '\'' +
                ", url='" + url + '\'' +
                ", repositoryUrl='" + repositoryUrl + '\'' +
                ", browseUrl='" + browseUrl + '\'' +
                '}';
    }

    public static class Builder {

        private String contentId;
        private Path path;
        private String url;
        private String repositoryUrl;
        private String browseUrl;

        public Builder() {
        }

        public Builder(@Nonnull Submodule submodule) {
            path(checkNotNull(submodule, "submodule").getPath());
            contentId(submodule.getContentId());
            url(submodule.getUrl());
            repositoryUrl(submodule.getRepositoryUrl());
            browseUrl(submodule.getBrowseUrl());
        }

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

            return this;
        }

        @Nonnull
        public SimpleSubmodule build() {
            checkState(path != null, "A path is required.");
            checkState(url != null, "A URL is required.");

            return new SimpleSubmodule(this);
        }

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

            return this;
        }

        @Nonnull
        public Builder path(@Nonnull Path value) {
            path = checkNotNull(value, "path");

            return this;
        }

        @Nonnull
        public Builder path(@Nonnull String value) {
            return path(new SimplePath(checkNotNull(value, "path")));
        }

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

            return this;
        }

        @Nonnull
        public Builder url(@Nonnull String value) {
            url = checkNotNull(value, "url");

            return this;
        }
    }
}
