import argparse
import sys

from .utils import load_data, store_output, check_help

import cyzil


def _parse_argument(args, docs):
    parser = argparse.ArgumentParser(description=docs)
    parser.add_argument(
        "--reference",
        required=True,
        type=str,
        help=(
            "Path to a reference file (supervised sequence), where",
            "each serntence is separated by '\n'",
            "Make sure the path includes the file extension.",
            "e.g., --reference ref.fr to load French translation reference."
        )
    )
    parser.add_argument(
        "--candidate",
        required=True,
        type=str,
        help=(
            "Path to a candiate file (sequence generated by a model), where",
            "each serntence is separated by '\n'",
            "Make sure the path includes the file extension.",
            "e.g., --candiate cand.fr to load French translation candidates."
        )
    )
    parser.add_argument(
        "--ngram",
        type=int,
        default=4,
        help=(
            "The maximum order of ngram to compute the score."
        )
    )
    parser.add_argument(
        "--tokenizer",
        default='space',
        choices=['space', 'nltk'],
        help=(
            "A method to tokenize input sentences.",
            "By default, a sentence is split by white spaces.",
            "options: space, nltk"
        )
    )
    parser.add_argument(
        "-o",
        "--output",
        type=str,
        help=(
            "A file path to store the output of `bleu_points`.",
            "It stores the output in csv format, where",
            "each row corresponds to a translation pair, and",
            "columns are in the following format: ",
            "precision, brevity penalty, bleu score"
        )
    )
    return parser.parse_args(args)


def bleu_corpus():
    """compute corpus-level bleu score
    cyzil-bleu-corpus [-h] [--reference] [--candiate]
                      [--ngram] [--tokenizer]
    required arguments:
    --reference   path to reference file, where each serntence is separated by '\\n'
    --candiate    path to candidate file, where each serntence is separated by '\\n'
    --ngram       the maximum order of ngram to compute the score

    optional arguments:
    --tokenizer   a way to tokenize sentences (white space by default);
                  options: space, nltk
    """
    check_help(bleu_corpus.__doc__)
    parser = _parse_argument(sys.argv[1:], bleu_corpus.__doc__)
    reference = load_data(parser.reference, parser.tokenizer)
    candidate = load_data(parser.candidate, parser.tokenizer)
    scores = cyzil.bleu_corpus(reference, candidate, parser.ngram)
    print(
        "Blue precision:", scores[0],
        "\nBleu brevity penalty:", scores[1],
        "\nBleu score:", scores[2]
    )


def bleu_points():
    """compute bleu score for each translation pair
    cyzil-bleu-points [-h] [--reference] [--candiate]
                      [--ngram] [--tokenizer] [--output]
    required arguments:
    --reference     path to reference file, where each serntence is separated by '\\n'
    --candiate      path to candidate file, where each serntence is separated by '\\n'
    --ngram         the maximum order of ngram to compute the score

    optional arguments:
    --tokenizer     a way to tokenize sentences (white space by default);
                    options: space, nltk
    -o, --output    a file path to store output in csv format
    """
    check_help(bleu_points.__doc__)
    parser = _parse_argument(sys.argv[1:], bleu_points.__doc__)
    reference = load_data(parser.reference, parser.tokenizer)
    candidate = load_data(parser.candidate, parser.tokenizer)
    scores = cyzil.bleu_points(reference, candidate, parser.ngram)
    if parser.output is not None:
        store_output(scores, parser.output)
    else:
        print(scores)
