package com.atlassian.bitbucket.internal.scm.git.lfs.rest.model;

import com.atlassian.bitbucket.internal.scm.git.lfs.BadBatchResponseException;
import com.atlassian.bitbucket.internal.scm.git.lfs.model.BatchResponse;
import com.atlassian.bitbucket.internal.scm.git.lfs.model.ResponseObject;
import com.atlassian.bitbucket.rest.RestMapEntity;
import org.codehaus.jackson.map.annotate.JsonSerialize;

import javax.annotation.Nonnull;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.atlassian.bitbucket.util.MoreCollectors.toImmutableList;

/**
 * REST/JSON model of a Git LFS Batch Response.
 * See JSON schema: https://github.com/github/git-lfs/blob/master/docs/api/http-v1-batch-response-schema.json
 */
@JsonSerialize
public class RestBatchResponse extends RestMapEntity {

    private static final String OBJECTS_KEY = "objects";

    @SuppressWarnings("unused")
    public RestBatchResponse() {
    }

    public RestBatchResponse(@Nonnull BatchResponse batchResponse) {
        put(OBJECTS_KEY, transform(batchResponse.getObjects(), RestResponseObject::new));
    }

    /**
     * This constructor is used by unit tests
     */
    public RestBatchResponse(@Nonnull Map<String, Object> values) {
        super(values);
    }

    /**
     * @throws BadBatchResponseException if the response is invalid
     */
    @Nonnull
    public BatchResponse fromRest() {
        return new BatchResponse(getObjects());
    }

    private List<ResponseObject> getObjects() {
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> objects = (List) get(OBJECTS_KEY);
        if (objects == null) {
            throw new BadBatchResponseException("Response is missing required '" + OBJECTS_KEY + "' attribute");
        }

        return objects.stream()
                .map(object -> RestResponseObject.valueOf(object).fromRest())
                .filter(Objects::nonNull)
                .collect(toImmutableList());
    }
}
