__seed__ = ["file_parser"]


def grade_file_parser(student_fuction):
    """Test solution to "Odds and Ends"

    Parameters
    ----------
    student_fuction: Callable[str]
        Student solution function.
    """
    import os
    from hashlib import sha224

    import numpy as np

    from bwsi_grader import compare_functions
    from bwsi_grader.print import print_passed

    def write_test_file(fname, list_length=10, items_per_entry=3):
        """Write test file used to evaluate student function.

        Parameters
        ----------
        fname: str
            File name.

        list_length: int, optional (default=10)
            Length of file.

        items_per_entry: int, optional (default=3)
            Max number of entries (food-category pairs) per line.
        """
        foods = {
            "dessert": ["cake", "cookies", "ice cream", "candy"],
            "vegetable": ["carrots", "spinach", "broccoli", "kale"],
            "meat": ["chicken", "pork", "steak", "tuna"],
            "fruit": ["apples", "peaches", "pears", "bananas"],
        }

        entries = []
        for key, values in foods.items():
            for value in values:
                entries.extend([f"{value}: {key}"])

        final_entries = []
        for i in range(list_length):
            choices = np.random.choice(
                entries, np.random.randint(1, items_per_entry), replace=False
            )
            final_entries.append(", ".join(choices))

        with open(fname, "w") as f:
            f.write("\n".join(final_entries))

    def solution(file_path):
        """Read in survey and determine the most common food of each type.

        Parameters
        ----------
        file_path : str
            Path to text file containing favorite food survey responses.

        Returns
        -------
        Dict[str, str]
            Dictionary with the key being food type and value being food.
        """
        from collections import Counter
        from itertools import chain

        with open(file_path, "r") as f:
            # read correctly formatted lines
            entries = list(
                filter(
                    lambda x: ": " in x,
                    chain(*[entry.split(", ") for entry in f.read().splitlines()]),
                )
            )

        responses = {}
        for entry in entries:
            food, food_type = entry.split(": ")
            responses.setdefault(food_type, []).append(food)

        return {
            k: Counter(sorted(v)).most_common()[0][0] for (k, v) in responses.items()
        }

    # generate random files and compare results
    foods_file = "favorite-foods.txt"
    try:
        for i in range(100):
            write_test_file(
                foods_file,
                list_length=np.random.randint(1, 50),
                items_per_entry=np.random.randint(2, 5),
            )
            compare_functions(
                student=student_fuction, soln=solution, fn_args=(foods_file,)
            )
    finally:
        os.remove(foods_file)

    print_passed(sha224(str.encode(__seed__[0])).hexdigest())
