import re


def metadata_field_count(tileSource, format, redactList):
    """
    Count how many metadata fields are likely to be shown to the user and how
    many could be redacted.

    :param tileSource: a large_image tile source.
    :param format: the vendor or None if unknown.
    :param redactList: the list of redactions (see get_redact_list).
    :returns: the count of shown and redactable fields.
    """
    shown = 0
    redactable = 0
    preset = 0
    metadata = tileSource.getInternalMetadata()
    for mainkey in metadata:
        if not isinstance(metadata[mainkey], dict):
            shown += 1
            if redactList['metadata'].get(mainkey):
                preset += 1
            else:
                redactable += 1
            continue
        for subkey in metadata[mainkey]:
            key = 'internal;%s;%s' % (mainkey, subkey)
            if format == 'aperio' and re.match(
                    r'^internal;openslide;(openslide.comment|tiff.ImageDescription)$', key):
                continue
            if re.match(r'^internal;openslide;openslide.level\[', key):
                continue
            if re.match(r'^internal;openslide;hamamatsu.(AHEX|MHLN)\[', key):
                continue
            shown += 1
            if redactList['metadata'].get(key):
                preset += 1
                continue
            if re.match(r'^internal;aperio_version$', key):
                continue
            if re.match(r'^internal;openslide;openslide\.(?!comment$)', key):
                continue
            if re.match(r'^internal;openslide;tiff.(ResolutionUnit|XResolution|YResolution)$', key):
                continue
            redactable += 1
    return {'visible': shown, 'redactable': redactable, 'automatic': preset}