#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import argparse
import hashlib
import os
import sys

from os.path import basename

from fontTools.ttLib import TTFont


def write_checksum(filepaths, stdout_write=False, use_ttx=False, include_tables=None, exclude_tables=None, do_not_cleanup=False):
    checksum_dict = {}
    for path in filepaths:
        if not os.path.exists(path):
            sys.stderr.write("[checksum.py] ERROR: " + path + " is not a valid file path" + os.linesep)
            sys.exit(1)

        if use_ttx:
            # append a .ttx extension to existing extension to maintain data about the binary that
            # was used to generate the .ttx XML dump.  This creates unique checksum path values for
            # paths that would otherwise not be unique with a file extension replacement with .ttx
            # An example is woff and woff2 web font files that share the same base file name:
            #
            #  coolfont-regular.woff  ==> coolfont-regular.ttx
            #  coolfont-regular.woff2 ==> coolfont-regular.ttx  (KAPOW! checksum data lost as this would overwrite dict value)
            temp_ttx_path = path + ".ttx"

            tt = TTFont(path)
            # important to keep the newlinestr value defined here as hash values will change across platforms
            # if platform specific newline values are assumed
            tt.saveXML(temp_ttx_path, newlinestr="\n", skipTables=exclude_tables, tables=include_tables)
            checksum_path = temp_ttx_path
        else:
            if include_tables is not None:
                sys.stderr.write("[checksum.py] -i and --include are not supported for font binary filepaths. \
                    Use these flags for checksums with the --ttx flag.")
                sys.exit(1)
            if exclude_tables is not None:
                sys.stderr.write("[checksum.py] -e and --exclude are not supported for font binary filepaths. \
                    Use these flags for checksums with the --ttx flag.")
                sys.exit(1)
            checksum_path = path

        file_contents = _read_binary(checksum_path)

        # store SHA1 hash data and associated file path basename in the checksum_dict dictionary
        checksum_dict[basename(checksum_path)] = hashlib.sha1(file_contents).hexdigest()

        # remove temp ttx files when present
        if use_ttx and do_not_cleanup is False:
            os.remove(temp_ttx_path)

    # generate the checksum list string for writes
    checksum_out_data = ""
    for key in checksum_dict.keys():
        checksum_out_data += checksum_dict[key] + "  " + key + "\n"

    # write to stdout stream or file based upon user request (default = file write)
    if stdout_write:
        sys.stdout.write(checksum_out_data)
    else:
        checksum_report_filepath = "checksum.txt"
        with open(checksum_report_filepath, "w") as file:
            file.write(checksum_out_data)


def check_checksum(filepaths):
    check_failed = False
    for path in filepaths:
        if not os.path.exists(path):
            sys.stderr.write("[checksum.py] ERROR: " + path + " is not a valid filepath" + os.linesep)
            sys.exit(1)

        with open(path, mode='r') as file:
            for line in file.readlines():
                cleaned_line = line.rstrip()
                line_list = cleaned_line.split(" ")
                # eliminate empty strings parsed from > 1 space characters
                line_list = list(filter(None, line_list))
                if len(line_list) == 2:
                    expected_sha1 = line_list[0]
                    test_path = line_list[1]
                else:
                    sys.stderr.write("[checksum.py] ERROR: failed to parse checksum file values" + os.linesep)
                    sys.exit(1)

                if not os.path.exists(test_path):
                    print(test_path + ": Filepath is not valid, ignored")
                else:
                    file_contents = _read_binary(test_path)
                    observed_sha1 = hashlib.sha1(file_contents).hexdigest()
                    if observed_sha1 == expected_sha1:
                        print(test_path + ": OK")
                    else:
                        print("-" * 80)
                        print(test_path + ": === FAIL ===")
                        print("Expected vs. Observed:")
                        print(expected_sha1)
                        print(observed_sha1)
                        print("-" * 80)
                        check_failed = True

    # exit with status code 1 if any fails detected across all tests in the check
    if check_failed is True:
        sys.exit(1)


def _read_binary(filepath):
    with open(filepath, mode='rb') as file:
        return file.read()


if __name__ == '__main__':
    parser = argparse.ArgumentParser(prog="checksum.py", description="A SHA1 hash checksum list generator and checksum testing script")
    parser.add_argument("-t", "--ttx", help="Calculate from ttx file", action="store_true")
    parser.add_argument("-s", "--stdout", help="Write output to stdout stream", action="store_true")
    parser.add_argument("-n", "--noclean", help="Do not discard *.ttx files used to calculate SHA1 hashes", action="store_true")
    parser.add_argument("-c", "--check", help="Verify checksum values vs. files", action="store_true")
    parser.add_argument("filepaths", nargs="+", help="One or more file paths.  Use checksum file path for -c/--check.  Use paths\
        to font files for all other commands.")

    parser.add_argument("-i", "--include", action="append", help="Included OpenType tables for ttx data dump")
    parser.add_argument("-e", "--exclude", action="append", help="Excluded OpenType tables for ttx data dump")

    args = parser.parse_args(sys.argv[1:])

    if args.check is True:
        check_checksum(args.filepaths)
    else:
        write_checksum(args.filepaths, stdout_write=args.stdout, use_ttx=args.ttx, do_not_cleanup=args.noclean, include_tables=args.include, exclude_tables=args.exclude)
