import spacy
from spacy.scorer import PRFScore
import typer
from pathlib import Path
from wasabi import Printer, table
import operator
import benepar

import clausecat_component
import clausecat_model
import clausecat_reader
import clause_segmentation
import clause_aggregation

msg = Printer()


def main(model_path: Path, eval_path: Path):
    """This script is used to evaluate the clausecat component"""

    nlp = spacy.load(model_path)
    reader = clausecat_reader.ClausecatCorpus(eval_path)
    examples = reader(nlp)

    clausecat = nlp.get_pipe("clausecat")

    scorer = {
        "POSITIVE": PRFScore(),
        "NEGATIVE": PRFScore(),
        "NEUTRAL": PRFScore(),
        "ANAMNESIS": PRFScore(),
    }

    for i, example in enumerate(examples):
        prediction = example.predicted
        reference = example.reference

        # Prediction
        prediction = clausecat(prediction)

        # Iterate through prediction and references
        for pred_clause, ref_clause in zip(prediction._.clauses, reference._.clauses):
            prediction_cats = pred_clause["cats"]
            reference_cats = ref_clause["cats"]
            prediction_class = max(prediction_cats.items(), key=operator.itemgetter(1))[
                0
            ]

            # Add to matrix
            for label in prediction_cats:
                if label != prediction_class:
                    prediction = 0
                else:
                    prediction = 1

                if prediction == 0 and reference_cats[label] != 0:
                    scorer[label].fn += 1

                elif prediction == 1 and reference_cats[label] != 1:
                    scorer[label].fp += 1

                elif prediction == 1 and reference_cats[label] == 1:
                    scorer[label].tp += 1

    # Printing
    textcat_data = []
    avg_fscore = 0
    avg_recall = 0
    avg_precision = 0

    for label in scorer:
        textcat_data.append(
            (
                label,
                round(scorer[label].fscore, 2),
                round(scorer[label].recall, 2),
                round(scorer[label].precision, 2),
            )
        )
        avg_fscore += scorer[label].fscore
        avg_recall += scorer[label].recall
        avg_precision += scorer[label].precision

    textcat_data.append(
        (
            "AVERAGE",
            round(avg_fscore / len(scorer), 2),
            round(avg_recall / len(scorer), 2),
            round(avg_precision / len(scorer), 2),
        )
    )

    header = ("Label", "F-Score", "Recall", "Precision")

    print(table(textcat_data, header=header, divider=True))


if __name__ == "__main__":
    typer.run(main)

[((15, 6, 15, 15), 'wasabi.Printer', 'Printer', ({}, {}), '()', False, 'from wasabi import Printer, table\n'), ((21, 10, 21, 32), 'spacy.load', 'spacy.load', ({(21, 21, 21, 31): 'model_path'}, {}), '(model_path)', False, 'import spacy\n'), ((22, 13, 22, 56), 'clausecat_reader.ClausecatCorpus', 'clausecat_reader.ClausecatCorpus', ({(22, 46, 22, 55): 'eval_path'}, {}), '(eval_path)', False, 'import clausecat_reader\n'), ((99, 4, 99, 19), 'typer.run', 'typer.run', ({(99, 14, 99, 18): 'main'}, {}), '(main)', False, 'import typer\n'), ((28, 20, 28, 30), 'spacy.scorer.PRFScore', 'PRFScore', ({}, {}), '()', False, 'from spacy.scorer import PRFScore\n'), ((29, 20, 29, 30), 'spacy.scorer.PRFScore', 'PRFScore', ({}, {}), '()', False, 'from spacy.scorer import PRFScore\n'), ((30, 19, 30, 29), 'spacy.scorer.PRFScore', 'PRFScore', ({}, {}), '()', False, 'from spacy.scorer import PRFScore\n'), ((31, 21, 31, 31), 'spacy.scorer.PRFScore', 'PRFScore', ({}, {}), '()', False, 'from spacy.scorer import PRFScore\n'), ((95, 10, 95, 58), 'wasabi.table', 'table', (), '', False, 'from wasabi import Printer, table\n'), ((45, 64, 45, 86), 'operator.itemgetter', 'operator.itemgetter', ({(45, 84, 45, 85): '(1)'}, {}), '(1)', False, 'import operator\n')]