#!/usr/bin/env python
# Copyright (c) 2012 The Native Client Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""
Usage:
 sha1check.py <hashfile

 where hashfile was generated by "sha1sum.py" (or the "sha1sum" utility)
 and has the format:

  da39a3ee5e6b4b0d3255bfef95601890afd80709 *filename

 sha1check.py will perform sha1 hash on filename (opened in
 binary mode) and compare the generated hash value with
 the hash value in the input hashfile.  If the two hashes
 don't match or filename doesn't exist, sha1check.py will
 return an error.
"""

from __future__ import print_function

import hashlib
import sys


class Error(Exception):
  pass


def VerifyHash(filename, sha1sum):
  try:
    # open file in binary mode & sha1 hash it
    h = hashlib.sha1()
    with open(filename, "rb") as f:
      h.update(f.read())
    filehash = h.hexdigest()

  except IOError:
    raise Error("unable to open file " + filename)
  except:
    raise Error("encountered an unexpected error")

  # verify the generated hash and embedded hash match
  if sha1sum.lower() != filehash.lower():
    print("Filename: %s" % filename)
    print("Expected hash: %s" % sha1sum)
    print("Actual hash: %s" % filehash)
    raise Error("sha1 checksum failed on file: " + filename)


def VerifyLine(line, verbose):
  # split the hash *filename into a pair
  parts = line.split()
  if len(parts) != 2:
    raise Error("Invalid sha1 line: '%s'" % line)

  sha1sum, name = parts

  # make sure filename started with '*' (binary mode)
  if not name or name[0] != '*':
    raise Error("input hash is not from a binary file")

  # remove leading '*' and any newlines from filename
  filename = name[1:]
  VerifyHash(filename, sha1sum)
  if verbose:
    print("sha1check.py: %s verified" % filename)

  return filename


def VerifyFile(file_input, verbose):
  rtn = []
  for line in file_input:
    rtn.append(VerifyLine(line, verbose))

  if not rtn:
    raise Error("No file hashes given on input")

  return rtn


def main():
  try:
    VerifyFile(sys.stdin, True)
  except Error as e:
    sys.stdout.write('sha1check.py: %s\n' % str(e))
    return 1

  return 0

# all files hashed with success
if __name__ == '__main__':
  sys.exit(main())
