#!/usr/bin/env python
import sys
import os
import argparse
import urlparse
import urllib
import urllib2
import hashlib
import math
import textwrap
import tarfile
import fnmatch
import errno
import tempfile
import shutil

class DownloadError(Exception):
    pass

class ChecksumError(Exception):
    pass

class ExtractionError(Exception):
    pass

TITAN_URL="http://www.eecg.utoronto.ca/~kmurray/titan/"


def parse_args():
    description = textwrap.dedent("""
                    Download and extract a Titan benchmark release into a
                    VTR-style directory structure.

                    If a previous matching titan release tar.gz file is found
                    does nothing (unless --force is specified).
                  """)
    parser = argparse.ArgumentParser(
                formatter_class=argparse.ArgumentDefaultsHelpFormatter
             )

    parser.add_argument("--titan_version",
                        default="1.2.10",
                        help="Titan release version to download")
    parser.add_argument("--vtr_flow_dir",
                        required=True,
                        help="The 'vtr_flow' directory under the VTR tree. "
                             "If specified this will extract the titan release, "
                             "placing benchmarks under vtr_flow/benchmarks/titan, "
                             "and architectures under vtr_flow/arch/titan ")
    parser.add_argument("--force",
                        default=False,
                        action="store_true",
                        help="Run extraction step even if directores etc. already exist")

    return parser.parse_args()

def main():

    args = parse_args()

    try:
        tar_gz_filename = "titan_release_" + args.titan_version + '.tar.gz'
        md5_filename = "titan_release_" + args.titan_version + '.md5'
        
        tar_gz_url = urlparse.urljoin(TITAN_URL, tar_gz_filename)
        md5_url = urlparse.urljoin(TITAN_URL, md5_filename)

        external_md5 = load_md5_from_url(md5_url)

        file_matches = False
        if os.path.isfile(tar_gz_filename):
            file_matches = md5_matches(tar_gz_filename, external_md5)

        if not args.force and file_matches:
            print "Found existing {} with matching checksum (skipping download and extraction)".format(tar_gz_filename)
        else:
            if os.path.isfile(tar_gz_filename) and not file_matches:
                print "Local file MD5 does not match remote MD5"

            print "Downloading {}".format(tar_gz_url)
            download_url(tar_gz_filename, tar_gz_url)

            print "Verifying {}".format(tar_gz_url)
            if not md5_matches(tar_gz_filename, external_md5):
                raise CheckSumError(tar_gz_filename)

            print "Extracting {}".format(tar_gz_filename)
            extract_to_vtr_flow_dir(args, tar_gz_filename)

    except DownloadError as e:
        print "Failed to download:", e
        sys.exit(1)
    except ChecksumError as e:
        print "File corrupt:", e
        sys.exit(2)
    except ExtractionError as e:
        print "Failed to extract titan release:", e
        sys.exit(3)

    sys.exit(0)


def download_url(filename, url):
    """
    Downloads the titan release
    """
    urllib.urlretrieve(url, filename, reporthook=download_progress_callback)

def verify_titan(tar_gz_filename, md5_url):
    """
    Performs checksum verification of downloaded titan release file
    """


    if(filename != tar_gz_filename):
        raise VerificationError("External MD5 appears to be for a different file. Was {} expected {}".format(filename, tar_gz_filename))

    print "Verifying checksum"
    local_md5 = hashlib.md5()
    with open(filename, "rb") as f:
        #Read in chunks to avoid reading the whole file into memory
        for chunk in iter(lambda: f.read(4096), b""):
            local_md5.update(chunk)

    if local_md5.hexdigest() != external_md5:
        raise ChecksumError("Checksum mismatch! Local {} expected {}".format(local_md5.hexdigest(), external_md5))
    print "OK"

def md5_matches(filename_to_check, reference_md5):

    local_md5 = hashlib.md5()
    with open(filename_to_check, "rb") as f:
        #Read in chunks to avoid reading the whole file into memory
        for chunk in iter(lambda: f.read(4096), b""):
            local_md5.update(chunk)

    if local_md5.hexdigest() != reference_md5:
        return False

    return True

def load_md5_from_url(md5_url):
    md5_data = urllib2.urlopen(md5_url)
    external_md5, filename = md5_data.read().split()

    return external_md5

def download_progress_callback(block_num, block_size, expected_size):
    """
    Callback for urllib.urlretrieve which prints a dot for every percent of a file downloaded
    """
    total_blocks = int(math.ceil(expected_size / block_size))
    progress_increment = int(math.ceil(total_blocks / 100))

    if block_num % progress_increment == 0:
        sys.stdout.write(".")
        sys.stdout.flush()
    if block_num*block_size >= expected_size:
        print ""

def extract_to_vtr_flow_dir(args, tar_gz_filename):
    """
    Extracts the 'arch' and 'benchmarks' directories of the titan release
    into their corresponding vtr directories
    """

    #Reference directories
    arch_dir = os.path.join(args.vtr_flow_dir, "arch")
    benchmarks_dir = os.path.join(args.vtr_flow_dir, "benchmarks")
    titan_benchmarks_extract_dir = os.path.join(benchmarks_dir, 'titan_blif')
    titan_other_benchmarks_extract_dir = os.path.join(benchmarks_dir, 'titan_other_blif')
    titan_arch_extract_dir = os.path.join(arch_dir, 'titan')

    if not args.force:
        #Check that all expected directories exist
        expected_dirs = [args.vtr_flow_dir, benchmarks_dir, arch_dir, titan_benchmarks_extract_dir, titan_arch_extract_dir]
        for dir in expected_dirs:
            if not os.path.isdir(dir):
                raise ExtractionError("{} should be a directory".format(dir))

    #Create a temporary working directory
    tmpdir = tempfile.mkdtemp(suffix="download_titan", dir=".")

    try:
        #We use a callback along with extractall() to only walk through the large tar.gz file
        #once (saving runtime). We then move the files to the correct directories, which should
        #be a cheap rename operation

        #Extract matching files into the temporary directory
        with tarfile.TarFile.open(tar_gz_filename, mode="r|*") as tar_file:
            tar_file.extractall(path=tmpdir, members=extract_callback(tar_file))

        #Move the extracted files to the relevant directories
        for dirpath, dirnames, filenames in os.walk(tmpdir):
            for filename in filenames:
                src_file_path = os.path.join(dirpath, filename)
                dst_file_path = None
                if fnmatch.fnmatch(src_file_path, "*/titan_release*/benchmarks/titan23/*/*/*.blif"):
                    dst_file_path = os.path.join(titan_benchmarks_extract_dir, filename)
                elif fnmatch.fnmatch(src_file_path, "*/titan_release*/benchmarks/other_benchmarks/*/*/*.blif"):
                    dst_file_path = os.path.join(titan_other_benchmarks_extract_dir, filename)
                else:
                    assert filename.endswith(".xml")
                    dst_file_path = os.path.join(titan_arch_extract_dir, filename)

                shutil.move(src_file_path, dst_file_path)

    finally:
        #Clean-up
        shutil.rmtree(tmpdir)

    print "Done"

def extract_callback(members):
    for tarinfo in members:
        if fnmatch.fnmatch(tarinfo.name, "titan_release*/benchmarks/titan23/*/*/*.blif"):
            print tarinfo.name
            yield tarinfo
        elif fnmatch.fnmatch(tarinfo.name, "titan_release*/benchmarks/other_benchmarks/*/*/*.blif"):
            print tarinfo.name
            yield tarinfo
        elif fnmatch.fnmatch(tarinfo.name, "titan_release*/arch/stratixiv*.xml"):
            print tarinfo.name
            yield tarinfo 


if __name__ == "__main__":
    main()
