package com.atlassian.bitbucket.internal.scm.git.lfs.embedded;

import com.atlassian.bitbucket.internal.scm.git.lfs.rest.storage.HttpRange;
import com.atlassian.bitbucket.repository.Repository;

import javax.annotation.Nonnull;
import java.util.Optional;

import static java.util.Objects.requireNonNull;

/**
 * Encapsulates details of a read request on the LFS object store
 */
public class ReadObjectRequest {

    private final String oid;
    private final HttpRange range;
    private final Repository repository;

    private ReadObjectRequest(@Nonnull Builder builder) {
        this.oid = builder.oid;
        this.repository = builder.repository;
        this.range = builder.range;
    }

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

    @Nonnull
    public String getOid() {
        return oid;
    }

    @Nonnull
    public Optional<HttpRange> getRange() {
        return Optional.ofNullable(range);
    }

    public static class Builder {

        private final String oid;
        private final Repository repository;
        private HttpRange range;

        /**
         * @param repository the repository where the object resides
         * @param oid the object identifier (a SHA256 digest)
         */
        public Builder(@Nonnull Repository repository, @Nonnull String oid) {
            this.repository = requireNonNull(repository, "repository");
            this.oid = requireNonNull(oid, "oid");
        }

        /**
         * @param range a byte range to be streamed if the storage service supports ranges. The store
         *              service is free to ignore the range specified.
         * @return {@code this}
         */
        public Builder range(HttpRange range) {
            this.range = range;
            return this;
        }

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