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

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

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

public class File {

    private final String contentId;
    private final Boolean executable;
    private final String path;
    private final Long size;

    private File(Builder builder) {
        contentId = builder.contentId;
        executable = builder.executable;
        path = builder.path;
        size = builder.size;
    }

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

    @Nullable
    public Boolean getExecutable() {
        return executable;
    }

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

    @Nullable
    public Long getSize() {
        return size;
    }

    @Nonnull
    public RpcFile toFile() {
        RpcFile.Builder builder = RpcFile.newBuilder()
                .setContentId(contentId)
                .setPath(ByteString.copyFromUtf8(path));
        if (executable != null) {
            builder.setExecutable(executable);
        }
        if (size != null) {
            builder.setSize(size);
        }

        return builder.build();
    }

    public static class Builder extends BuilderSupport {

        private final String contentId;
        private final String path;

        private Boolean executable;
        private Long size;

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

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

        @Nonnull
        public Builder executable(@Nullable Boolean value) {
            executable = value;

            return this;
        }

        @Nonnull
        public Builder size(@Nullable Long value) {
            size = value;

            return this;
        }
    }
}
