package ru.yandex.qe.dispenser.domain.util;

import java.util.Collection;
import java.util.Collections;
import java.util.stream.Stream;

public abstract class Page<T> {
    public static final Page<?> EMPTY = of(Collections.emptyList(), 0);

    final long totalCount;

    public static <T> Page<T> of(final Collection<T> collection, final long totalCount) {
        return new CollectionPage<>(collection, totalCount);
    }

    public static <T> Page<T> of(final Stream<T> stream, final long totalCount) {
        return new StreamPage<>(stream, totalCount);
    }

    private static class StreamPage<T> extends Page<T> {
        private final Stream<T> items;

        protected StreamPage(final Stream<T> items, final long totalCount) {
            super(totalCount);
            this.items = items;
        }

        @Override
        public Stream<T> getItems() {
            return items;
        }
    }

    private static class CollectionPage<T> extends Page<T> {
        private final Collection<T> items;

        protected CollectionPage(final Collection<T> items, final long totalCount) {
            super(totalCount);
            this.items = items;
        }

        @Override
        public Stream<T> getItems() {
            return items.stream();
        }
    }

    protected Page(final long totalCount) {
        this.totalCount = totalCount;
    }

    @SuppressWarnings("unchecked")
    public static <T> Page<T> empty() {
        return (Page<T>) EMPTY;
    }

    public abstract Stream<T> getItems();

    public long getTotalCount() {
        return totalCount;
    }
}

