#!/usr/bin/env python 
import os, sys
import zlib
import time

def crc(fileName):
    prev = 0
    for eachLine in open(os.getcwd()+"/"+fileName,"rb"):
        prev = zlib.crc32(eachLine, prev)
    return "%X"%(prev & 0xFFFFFFFF)
    
def file_len(fname):
    with open(fname,'r') as f:
        for i, l in enumerate(f):
            pass
    return i + 1
    
def fcount(path):
    count = 0
    for f in os.listdir(path):
        if os.path.isfile(os.path.join(path, f)):
            count += 1
    return count
    
start_time = time.time()
    
# Variables defined
lineCounter = 0
currData = ''
cdedInst = 0
cdedLineCounter = 0
nlcdInst = 0
nlcdLineCounter = 0
nlcd2011Inst = 0
nlcd2011LineCounter = 0
nlcd2016Inst = 0
nlcd2016LineCounter = 0
nlcd2021Inst = 0
nlcd2021LineCounter = 0
errorCount = 0

numFiles = file_len("reqHashes.txt")
print("Total number of required data files: " + str(numFiles))
if fcount('cded') > 3:
    cdedInst = 1
    numCdedFiles = file_len("cdedHashes.txt")
    print("Total number of optional CDED files: " + str(numCdedFiles))
if fcount('nlcd') > 3:
    nlcdInst = 1
    numNlcdFiles = file_len("nlcdHashes.txt")
    print("Total number of optional 2006 NLCD files: " + str(numNlcdFiles))
if os.path.isdir('nlcd2011'):
    if fcount('nlcd2011') > 3:
        nlcd2011Inst = 1
        numNlcd2011Files = file_len("nlcd2011Hashes.txt")
        print("Total number of optional 2011 NLCD files: " + str(numNlcd2011Files))
if os.path.isdir('nlcd2016'):
    if fcount('nlcd2016') > 3:
        nlcd2016Inst = 1
        numNlcd2016Files = file_len("nlcd2016Hashes.txt")
        print("Total number of optional 2016 NLCD files: " + str(numNlcd2016Files))
if os.path.isdir('nlcd2021'):
    if fcount('nlcd2021') > 3:
        nlcd2021Inst = 1
        numNlcd2021Files = file_len("nlcd2021Hashes.txt")
        print("Total number of optional 2021 NLCD files: " + str(numNlcd2021Files))

readFile = open("reqHashes.txt","r")
for eachLine in readFile:
    lineList = eachLine.split(',')
    try:
        crcSum = crc(lineList[0])
        if lineList[1].rstrip() != crcSum:
            print ("Bad data in file: " + lineList[0] + " (" + crcSum + " != " + lineList[1].rstrip() + ")")
    except IOError as e:
        errorCount += 1
        if e[0] == 2:
            print ("File missing: " + lineList[0])
        elif e[0] == 13:
            print ("Permission denied: " + lineList[0])
        else:
            print ("Error code " + e[0] + ": " + lineList[0])
    fileList = lineList[0].split('/')
    if currData != fileList[0]:
        print ("Checking " + fileList[0] + " data.")
        currData = fileList[0]
    lineCounter += 1
    sys.stdout.write(str(lineCounter) + "/" + str(numFiles) + "\r")
    sys.stdout.flush()

if cdedInst == 1:
    print ("Checking cded data.")
    readFile = open("cdedHashes.txt","r")
    for eachLine in readFile:
        lineList = eachLine.split(',')
        crcSum = crc(lineList[0])
        cdedLineCounter += 1
        sys.stdout.write(str(cdedLineCounter) + "/" + str(numCdedFiles) + "\r")
        sys.stdout.flush()
        if lineList[1].rstrip() != crcSum:
            print ("Bad data in file: " + lineList[0] + " (" + crcSum + " != " + lineList[1].rstrip() + ")")

else:
    print("Optional CDED files do not appear to be installed.")

if nlcdInst == 1:
    print ("Checking 2006 nlcd data.")
    readFile = open("nlcdHashes.txt","r")
    for eachLine in readFile:
        lineList = eachLine.split(',')
        crcSum = crc(lineList[0])
        nlcdLineCounter += 1
        sys.stdout.write(str(nlcdLineCounter) + "/" + str(numNlcdFiles) + "\r")
        sys.stdout.flush()
        if lineList[1].rstrip() != crcSum:
            print ("Bad data in file: " + lineList[0] + " (" + crcSum + " != " + lineList[1].rstrip() + ")")

else:
    print("Optional 2006 nlcd files do not appear to be installed.")

if nlcd2011Inst == 1:
    print ("Checking 2011 nlcd data.")
    readFile = open("nlcd2011Hashes.txt","r")
    for eachLine in readFile:
        lineList = eachLine.split(',')
        crcSum = crc(lineList[0])
        nlcd2011LineCounter += 1
        sys.stdout.write(str(nlcd2011LineCounter) + "/" + str(numNlcd2011Files) + "\r")
        sys.stdout.flush()
        if lineList[1].rstrip() != crcSum:
            print ("Bad data in file: " + lineList[0] + " (" + crcSum + " != " + lineList[1].rstrip() + ")")

else:
    print("Optional 2011 nlcd files do not appear to be installed.")

if nlcd2016Inst == 1:
    print ("Checking 2016 nlcd data.")
    readFile = open("nlcd2016Hashes.txt","r")
    for eachLine in readFile:
        lineList = eachLine.split(',')
        crcSum = crc(lineList[0])
        nlcd2016LineCounter += 1
        sys.stdout.write(str(nlcd2016LineCounter) + "/" + str(numNlcd2016Files) + "\r")
        sys.stdout.flush()
        if lineList[1].rstrip() != crcSum:
            print ("Bad data in file: " + lineList[0] + " (" + crcSum + " != " + lineList[1].rstrip() + ")")

else:
    print("Optional 2016 nlcd files do not appear to be installed.")

if nlcd2021Inst == 1:
    print ("Checking 2021 nlcd data.")
    readFile = open("nlcd2021Hashes.txt","r")
    for eachLine in readFile:
        lineList = eachLine.split(',')
        crcSum = crc(lineList[0])
        nlcd2021LineCounter += 1
        sys.stdout.write(str(nlcd2021LineCounter) + "/" + str(numNlcd2021Files) + "\r")
        sys.stdout.flush()
        if lineList[1].rstrip() != crcSum:
            print ("Bad data in file: " + lineList[0] + " (" + crcSum + " != " + lineList[1].rstrip() + ")")

else:
    print("Optional 2021 nlcd files do not appear to be installed.")

elapsed_time = time.time() - start_time

if errorCount == 0:
    print("No errors were detected.")
elif errorCount == 1:
    print("1 error was detected.")
else:
    print(str(errorCount) + " errors were detected.")

print("File check took " + str(elapsed_time) + " seconds.")
