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

import com.atlassian.bitbucket.mesh.git.ref.Ref;
import com.atlassian.bitbucket.mesh.git.ref.RefType;
import com.atlassian.bitbucket.mesh.repository.Repository;
import com.atlassian.bitbucket.mesh.rpc.v1.RpcPullRequestRef;
import com.atlassian.bitbucket.mesh.util.BuilderSupport;
import com.google.protobuf.ByteString;

import javax.annotation.Nonnull;

import static java.util.Objects.requireNonNull;

public class PullRequestRef implements Ref {

    private final String id;
    private final String latestCommit;
    private final Repository repository;

    private PullRequestRef(Builder builder) {
        id = builder.id;
        latestCommit = builder.latestCommit;
        repository = builder.repository;
    }

    @Nonnull
    @Override
    public String getId() {
        return id;
    }

    @Nonnull
    @Override
    public String getLatestCommit() {
        return latestCommit;
    }

    @Nonnull
    @Override
    public String getObjectId() {
        return latestCommit;
    }

    @Nonnull
    @Override
    public RefType getType() {
        //Technically if the ref isn't under refs/heads/ it's not a branch, but this is consistent
        //with how Bitbucket Server handles IDs so it will work for the moment
        return id.startsWith("refs/tags/") ? RefType.TAG : RefType.BRANCH;
    }

    @Nonnull
    public Repository getRepository() {
        return repository;
    }

    @Nonnull
    public RpcPullRequestRef toPullRequestRef() {
        return RpcPullRequestRef.newBuilder()
                .setId(ByteString.copyFromUtf8(id))
                .setLatestCommit(latestCommit)
                .setRepository(repository.getId())
                .build();
    }

    public static class Builder extends BuilderSupport {

        private final String id;
        private final Repository repository;

        private String latestCommit;

        public Builder(@Nonnull Repository repository, @Nonnull String id) {
            this.id = requireNonBlank(id, "id");
            this.repository = requireNonNull(repository, "repository");
        }

        @Nonnull
        public PullRequestRef build() {
            requireNonBlank(latestCommit, "latestCommit");

            return new PullRequestRef(this);
        }

        @Nonnull
        public Builder latestCommit(@Nonnull String value) {
            latestCommit = requireNonBlank(value, "latestCommit");

            return this;
        }
    }
}
