package com.atlassian.bitbucket.rest.util;

import com.atlassian.bitbucket.rest.RestMapEntity;
import com.atlassian.bitbucket.util.Page;
import com.atlassian.bitbucket.util.PageRequest;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import org.codehaus.jackson.map.annotate.JsonSerialize;

import java.util.function.Function;

@JsonSerialize
public class RestPage<T> extends RestMapEntity {

    private static final String FILTER = "filter";
    private static final String IS_LAST_PAGE = "isLastPage";
    private static final String LIMIT = "limit";
    private static final String NEXT_PAGE_START = "nextPageStart";
    private static final String SIZE = "size";
    private static final String START = "start";
    private static final String VALUES = "values";

    public RestPage(Page<T> page) {
        this(page, page.getValues());
    }

    public <E> RestPage(Page<? extends E> page, Function<E, ? extends T> restTransform) {
        this(page, Iterables.transform(page.getValues(), restTransform::apply));
    }

    public RestPage(int start, int limit, int size, boolean lastPage, Iterable<T> values, PageRequest nextPageRequest) {
        put(SIZE, size);
        put(LIMIT, limit);
        put(IS_LAST_PAGE, lastPage);
        put(VALUES, ImmutableList.copyOf(values));
        put(START, start);
        if (nextPageRequest != null) {
            put(NEXT_PAGE_START, nextPageRequest.getStart());
        }
    }

    private RestPage(Page<?> page, Iterable<T> pageValues) {
        this(page.getStart(), page.getLimit(), page.getSize(), page.getIsLastPage(), pageValues, page.getNextPageRequest());
    }
}
