#!/usr/bin/env python
# Dan Blankenberg
"""
A script for calculating secure hashes / message digests.
"""
import hashlib
import optparse
from collections import OrderedDict

HASH_ALGORITHMS = ['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512']
CHUNK_SIZE = 2 ** 20  # 1mb


def __main__():
    # Parse Command Line
    parser = optparse.OptionParser()
    parser.add_option('-a', '--algorithm', dest='algorithms', action='append', type="string", help='Algorithms to use, eg. (md5, sha1, sha224, sha256, sha384, sha512)')
    parser.add_option('-i', '--input', dest='input', action='store', type="string", help='Input filename')
    parser.add_option('-o', '--output', dest='output', action='store', type="string", help='Output filename')
    (options, args) = parser.parse_args()

    algorithms = OrderedDict()
    for algorithm in options.algorithms:
        assert algorithm in HASH_ALGORITHMS, "Invalid algorithm specified: %s" % (algorithm)
        assert algorithm not in algorithms, "Specify each algorithm only once."
        algorithms[algorithm] = hashlib.new(algorithm)
    assert options.algorithms, "You must provide at least one algorithm."
    assert options.input, "You must provide an input filename."
    assert options.output, "You must provide an output filename."

    with open(options.input, 'rb') as fh:
        while True:
            chunk = fh.read(CHUNK_SIZE)
            if chunk:
                for algorithm in algorithms.values():
                    algorithm.update(chunk)
            else:
                break

    with open(options.output, 'w') as output:
        output.write('#%s\n' % ('\t'.join(algorithms.keys())))
        output.write('%s\n' % ('\t'.join(x.hexdigest() for x in algorithms.values())))


if __name__ == "__main__":
    __main__()
