"""Entry point module: validate-execution

This file should not be modified.
"""

import csv
import logging
import os

from collections import Counter

logger = logging.getLogger(__name__)


def entry_point(output, reference, activity_index, file_index, result, score):
    """Private entry point.

    Test the execution of the system on each validation data set provided in
    container_output directory

    Args:
        output (str): Path to experiment output json file
        reference (str): Path to reference json file
        file_index (str): Path to file index json file for test set
        activity_index (str): Path to activity index json file for test set
        result (str): Path to result of the ActEV scorer
        score (bool): Whether scoring the system output against a reference

    """
    # go into the right directory to execute the script
    current_path = os.path.dirname(__file__)
    execution_validation_dir = os.path.join(
        current_path, '../implementation/validate_execution')
    installation_script = os.path.join(execution_validation_dir, 'install.sh')
    scoring_cmd = 'python2 ' + os.path.join(
        execution_validation_dir, 'ActEV_Scorer',
        'ActEV_Scorer.py ActEV18_AD -v ')

    scoring_cmd += " -s " + os.path.realpath(output)
    scoring_cmd += " -r " + os.path.realpath(reference) if reference else " "
    scoring_cmd += " -a " + os.path.realpath(activity_index)
    scoring_cmd += " -f " + os.path.realpath(file_index)
    scoring_cmd += " -o " + os.path.realpath(result) if result else " "
    scoring_cmd += " " if score else " -V"

    if not result and score:
        raise Exception("Please provide a -R option when using --score")

    # status is a 16-bit long integer
    # The 8 strongest bits are exit_code
    # The 8 weakest bits are signal_number
    cmd = 'cd ' + execution_validation_dir + '; '
    cmd += '. ' + installation_script + ';' + scoring_cmd
    status = os.system(cmd)
    exit_code = status >> 8
    signal_number = status & (2**8 - 1)
    if status != 0:
        if signal_number == 2:  # SIGINT
            raise KeyboardInterrupt
        else:
            raise Exception("Error occured in install.sh or score.sh")

    # If the system output is scored, make it also check the alignments
    # Produced by the scorer. This is a reproducibility check made to compare
    # A system output against another.
    if score and result:
        # Count the CD/FA/MD labels in the second column
        # (CorrectDetection/FalseAlarm/MissedDetection)
        # And calculate and display a similarity score
        alignments_filepath = os.path.join(result, 'alignment.csv')
        with open(alignments_filepath) as alignments_file:
            alignments_cursor = csv.reader(alignments_file, delimiter='|')
            classification_results = Counter(
                [row[1] for row in alignments_cursor])
            cd = classification_results.get('CD', 0)
            fa = classification_results.get('FA', 0)
            md = classification_results.get('MD', 0)
            similarity_score = (fa + md) / (fa + md + cd)
            logger.info('''Similarity score:
            (FP + FN) / (FP + FN + TP): ({} + {}) / ({} + {} + {}) = {}
            '''.format(fa, md, fa, md, cd, similarity_score))
