""" 
Workflow parameters:
 * job description
 * number of positions to fill (defined)
 * number to invite (defined)
 * number of candidates (random)

 * source more candidates if less on the lists after screening using 
   'if' or 'while' statements
"""

import random
from collections import Counter

def candidate_apply(template):
    """ generate a candidate profile """
    import copy
    def randomize(node):
        for key in node:
            if isinstance(node[key], dict):
                node[key] = randomize(node[key])
            else:
                node[key] = random.choice(node[key])
        return node
    return randomize(copy.deepcopy(template))

def screen_candidates(job, profiles, min_score, number_to_invite):
    """ screen all candidate profiles and returns a selection list """

    profiles_q = [profile['qualifications'] for profile in profiles]
    job_q = job['qualifications']
    for a, b in zip(profiles_q, profiles):
        score = Counter(job_q[key] == val for key, val in a.items())[True]
        if a['experience'] > job_q['experience']:
            score += 1
        b['score'] = score
    truncated = [p for p in profiles if p['score'] >= min_score]
    revsorted = sorted(truncated, reverse=True, key=lambda k: k['score'])
    return revsorted[0:number_to_invite]

def interview_candidates(job, profiles, number_to_fill):
    """ from a selection list sort all selected candidates and selects the 
    best matching profiles """

    profiles_c = [profile['contract conditions'] for profile in profiles]
    job_c = job['contract conditions']
    for a, b in zip(profiles_c, profiles):
        score = Counter(job_c[key] == val for key, val in a.items())[True]
        if a['salary'] <= job_c['salary']:
            score += 1
        # bonus for presentation and personal skills
        score += random.choice(range(4))
        b['score'] += score
    revsorted = sorted(profiles, reverse=True, key=lambda k: k['score'])
    return revsorted[0:number_to_fill]

def candidates_apply(template, max_applicants=100):
    """ return the applications from a number of applicants """
    num_applicants = random.randint(0, max_applicants)
    return [candidate_apply(template) for index in range(num_applicants)]