import random
import unittest

from Matching.GroupingAlgo import group
from itertools import combinations

random.seed(1000)


# PRE SETUP
class MockUser:
    def __init__(self, state):
        self.state = {"state": state}

    def __repr__(self):
        return str(self.state['state'])


# converts two MockUsers to distinguishable key
def pair_to_key(a, b):
    sorted = [a.state['state'], b.state['state']]
    sorted.sort()
    return "{}|{}".format(sorted[0], sorted[1])


def setup_distances(mock_users, distance_list):
    distances = {}
    i = -1
    for a, b in combinations(mock_users, 2):
        i += 1
        distances[pair_to_key(a, b)] = distance_list[i]
    return distances


class TestGroupMatchingAlgo(unittest.TestCase):
    def test_a_star_grouping_mock(self):
        # SETUP
        number_of_users = 50
        distances = [random.uniform(1, 15) for user in range(int(number_of_users * (number_of_users - 1) / 2))]
        mock_users = [MockUser(i) for i in range(number_of_users)]
        distance_map = setup_distances(mock_users, distances)

        # ACTION
        grouping_result = group(mock_users, lambda x, y: distance_map[pair_to_key(x, y)], 2, 6)

        # RESULT
        print(grouping_result)
        # all created groups are maximum 6, minimum 2
        for user_group in grouping_result:
            self.assertTrue(len(user_group) <= 6)
            self.assertTrue(len(user_group) >= 2)
