#!/usr/bin/env python
# coding: utf-8

# Copyright (c) Simula Research Laboratory.
# Distributed under the terms of the Modified BSD License.

from __future__ import print_function

import os
from pathlib import PurePath

from globmatch import glob_match


def check_dirs(source_dir, build_dir, known_excludes=None):
    """Run a check of a generated package manifest.

    The generated manifest will be checked against its source directory,
    and any unincluded files will be reported.  Any files declared
    explicitly in MAINFEST.in that are missing will also be reported.
    Any files that should intentionally not be included should be passed
    in the known_excludes argument.
    """

    return check_iterables(
        filter(os.path.isfile, os.walk(source_dir)),
        filter(os.path.isfile, os.walk(build_dir)),
        known_excludes=known_excludes,
        )


def check_filelist(filelist, known_excludes=None):
    """Check the files found in a FileList.

    filelist: distutils.FileList
        The file list object generated by a distutil command.
    """
    if filelist.allfiles is None:
        filelist.findall()
    return check_iterables(
        filelist.allfiles,
        filelist.files,
        known_excludes=known_excludes,
        )


def check_iterables(source, dist, known_excludes=None):
    """Check the files in the two iterables against each other.

    Any extra files in dist will be reported unconditionally, while any extra
    files in source will be reported unless it matches a glob in known_excludes.

    A report is made using print().

    Returns:
        A bitfield value with the following values:
            == 0 if no extra files were found
            |= 1 if extra files were found in dist
            |= 2 if extra files were found in source that were not excluded
    """
    source = set(PurePath(p) for p in source)
    dist = set(PurePath(p) for p in dist)

    retval = 0

    for missing in dist - source:
        retval |= 1
        print('Missing file: %r' % str(missing))

    for extra in filter(lambda x: not glob_match(x, known_excludes), source - dist):
        retval |= 2
        print('Extra file: %r' % str(extra))

    return retval
