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

import com.atlassian.bitbucket.mesh.rpc.v1.RpcBranch;
import com.google.protobuf.ByteString;

import javax.annotation.Nonnull;

import static java.util.Objects.requireNonNull;

/**
 * A {@link Ref} denoting a branch in the repository.
 */
public class Branch extends AbstractRef {

    private final boolean isDefault;

    private Branch(@Nonnull Builder builder) {
        super(builder);

        isDefault = builder.isDefault;
    }

    @Nonnull
    public static Branch fromBranch(@Nonnull RpcBranch branch) {
        requireNonNull(branch, "branch");
        return new Builder()
                .id(branch.getId().toStringUtf8())
                .isDefault(branch.getDefault())
                .latestCommit(branch.getLatestCommit())
                .build();
    }

    /**
     * Indicates whether this branch is the default branch for the repository.
     *
     * @return {@code true} for the default branch; otherwise, {@code false}
     */
    public boolean isDefault() {
        return isDefault;
    }

    @Nonnull
    public RpcBranch toBranch() {
        return RpcBranch.newBuilder()
                .setDefault(isDefault)
                .setLatestCommit(getLatestCommit())
                .setId(ByteString.copyFromUtf8(getId()))
                .build();
    }

    @Override
    public String toString() {
        return "Branch{id='" + getId() + "', latestCommit='" + getLatestCommit() + "'}";
    }

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

        private boolean isDefault;

        public Builder() {
            super(RefType.BRANCH);
        }

        public Builder(Branch branch) {
            super(RefType.BRANCH);

            isDefault = branch.isDefault;

            id(branch.getId());
            latestCommit(branch.getLatestCommit());
        }

        @Nonnull
        @Override
        public Branch build() {
            return new Branch(self());
        }

        @Nonnull
        public Builder isDefault(boolean isDefault) {
            this.isDefault = isDefault;
            return self();
        }

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