#!/usr/bin/python3

"""Check if a rip appears to have been successful."""

import os
import re
import sys
import decimal


def usage(retval):
    """Output a usage message and exit(retval)."""
    if retval:
        write = sys.stderr.write
    else:
        write = sys.stdout.write

    write('Usage: {} --rip-progress-file foo.rip-output --rip-result-file foo.ogm\n'.format(sys.argv[0]))

    sys.exit(retval)


def is_nondecreasing(list_):
    """Return True iff elements of list_ are nondecreasing."""
    for element1, element2 in zip(list_, list_[1:]):
        if element1 > element2:
            return False
    return True


def deduplicate(list_):
    """Deduplicate list_."""
    set_ = set(list_)

    list_[:] = list(set_)


def file_is_good(rip_progress_filename, rip_result_filename):
    """Check if filename describing a rip (EG, a HandBrakeCLI output file) looks like a successful rip."""
    rip_result_length = os.path.getsize(rip_result_filename)

    percentages = []

    percent_regex = re.compile(rb'^.*task 1 of 1, ([0-9][0-9]*\.[0-9][0-9]*) %.*$')

    with open(rip_progress_filename, 'rb') as file_:
        for line in file_:
            line2 = line.replace(b'\r', b'\n').rstrip(b'\n')
            for line3 in line2.split(b'\n'):
                # print('checking %s' % line3)
                match_obj = percent_regex.match(line3)
                if match_obj is not None:
                    string = match_obj.group(1).decode('ISO-8859-1')
                    percentage = decimal.Decimal(string)
                    percentages.append(percentage)

    if not is_nondecreasing(percentages):
        sys.stderr.write('{}: Percentages are not nondecreasing\n'.format(sys.argv[0]))
        return False

    deduplicate(percentages)

    if len(percentages) < 2:
        sys.stderr.write('{}: Less than 2 distinct percentages found\n'.format(sys.argv[0]))
        return False

    percentages.sort()

    # This is how much the percentage grew between the last 2 percentages
    difference = percentages[-1] - percentages[-2]

    # This is what would be the next one (if, sometimes, it weren't for the fact that we don't grow past 100%)
    next_percentage = percentages[-1] + difference

    # Small files tend to have lower percentages, even for good rips.  Cope.  :)
    if rip_result_length < 20*1024*1024:
        min_acceptable_percentage = '95'
    else:
        min_acceptable_percentage = '99'

    if next_percentage >= decimal.Decimal(min_acceptable_percentage):
        return True

    return False


def main():
    """Check handrake cli output for possible rip failure."""
    rip_progress_filename = None
    rip_result_filename = None
    while sys.argv[1:]:
        if sys.argv[1] == '--rip-progress-file':
            rip_progress_filename = sys.argv[2]
            del sys.argv[1]
        elif sys.argv[1] == '--rip-result-file':
            rip_result_filename = sys.argv[2]
            del sys.argv[1]
        elif sys.argv[1] in ('--help', '-h'):
            usage(0)
        else:
            sys.stderr.write('{}: Unrecognized option: {}\n'.format(sys.argv[0], sys.argv[1]))
            usage(1)
        del sys.argv[1]

    if rip_progress_filename is None:
        sys.stderr.write('{}: --rip-progress-file is a required argument\n'.format(sys.argv[0]))
        usage(1)

    if rip_result_filename is None:
        sys.stderr.write('{}: --rip-result-file is a required argument\n'.format(sys.argv[0]))
        usage(1)

    if file_is_good(rip_progress_filename, rip_result_filename):
        sys.exit(0)
    else:
        string = ('{}: Rip described by:\n{}\n..._appears_ to be bad, but check ' +
                  'on that with vi and/or mplayer.\n').format(sys.argv[0], rip_progress_filename)
        sys.stderr.write(string + '\n')
        sys.exit(1)


main()