def make_manifest_collection(
        pagination: Pagination, label: str, collection_id: str,
        per_page: int, base_url: str, page_num: Optional[int] = None,
        coll_counts: Optional[Tuple[int, str, int]] = None) -> dict:
    """Generate a IIIF collection.

    :param pagination:      Pagination query for all manifests of the
                            collection
    :param label:           Label for the collection
    :param collection_id:   Identifier of the collection
    :param base_url:        Root URL for the application,
                            e.g. https://example.com
    :param page_num:        Number of the collection page to display
    :returns:               The generated IIIF collection
    """
    collection_url = f'{base_url}/iiif/collection/{collection_id}'
    if page_num is not None:
        page_id = 'p{}'.format(page_num)
    else:
        page_id = 'top'
    collection = {
        "@context": "http://iiif.io/api/presentation/2/context.json",
        "@id": f'{base_url}/iiif/collection/{collection_id}/{page_id}',
        "@type": "sc:Collection",
        "total": pagination.total,
        "label": label,
    }
    if page_id == 'top':
        collection.update({
            "first": f'{collection_url}/p1',
            "last": f'{collection_url}/p{pagination.pages}'
        })
    else:
        if collection_id != 'index':
            collection['within'] = f'{collection_url}/top'
        collection.update({
            'startIndex': (pagination.page - 1) * pagination.per_page,
            'manifests': [{
                '@id': f'{base_url}/iiif/{m.id}/manifest',
                '@type': 'sc:Manifest',
                'label': m.label,
                'attribution': m.manifest['attribution'],
                'logo': m.manifest['logo'],
                'thumbnail': m.manifest.get(
                    'thumbnail',
                    m.manifest['sequences'][0]['canvases'][0]['thumbnail'])
            } for m in pagination.items]
        })
        if page_num == 1:
            collection['collections'] = []
            for cid, label, num_manifs in coll_counts:
                if not num_manifs:
                    continue
                # We create a mock pagination object that does not have
                # an underlying query, since we're only going to need
                # the manifest count when generating the top-level collection
                manifests_pagination = Pagination(
                    None, 1, per_page, num_manifs, None)
                iiif_coll = make_manifest_collection(
                    manifests_pagination, label, cid, None)
                collection['collections'].append(iiif_coll)
        if 'collections' in collection and not collection['collections']:
            del collection['collections']
        if pagination.has_next:
            collection['next'] = f'{collection_url}/p{pagination.next_num}'
        if pagination.has_prev:
            collection['prev'] = f'{collection_url}/p{pagination.prev_num}'
    return collection