# Copyright (c) 2015, Google Inc.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
"""Extracts archives."""

import hashlib
import optparse
import os
import os.path
import tarfile
import shutil
import sys
import zipfile


def CheckedJoin(output, path):
    """
    CheckedJoin returns os.path.join(output, path). It checks that the resulting
    path is under output, but shouldn't be used on untrusted input.
    """
    path = os.path.normpath(path)
    if os.path.isabs(path) or path.startswith("."):
        raise ValueError(path)
    return os.path.join(output, path)


class FileEntry(object):

    def __init__(self, path, mode, fileobj):
        self.path = path
        self.mode = mode
        self.fileobj = fileobj


class SymlinkEntry(object):

    def __init__(self, path, mode, target):
        self.path = path
        self.mode = mode
        self.target = target


def IterateZip(path):
    """
    IterateZip opens the zip file at path and returns a generator of entry objects
    for each file in it.
    """
    with zipfile.ZipFile(path, "r") as zip_file:
        for info in zip_file.infolist():
            if info.filename.endswith("/"):
                continue
            yield FileEntry(info.filename, None, zip_file.open(info))


def IterateTar(path, compression):
    """
    IterateTar opens the tar.gz or tar.bz2 file at path and returns a generator of
    entry objects for each file in it.
    """
    with tarfile.open(path, "r:" + compression) as tar_file:
        for info in tar_file:
            if info.isdir():
                pass
            elif info.issym():
                yield SymlinkEntry(info.name, None, info.linkname)
            elif info.isfile():
                yield FileEntry(info.name, info.mode,
                                tar_file.extractfile(info))
            else:
                raise ValueError('Unknown entry type "%s"' % (info.name, ))


def main(args):
    parser = optparse.OptionParser(usage="Usage: %prog ARCHIVE OUTPUT")
    parser.add_option(
        "--no-prefix",
        dest="no_prefix",
        action="store_true",
        help="Do not remove a prefix from paths in the archive.",
    )
    options, args = parser.parse_args(args)

    if len(args) != 2:
        parser.print_help()
        return 1

    archive, output = args

    if not os.path.exists(archive):
        # Skip archives that weren't downloaded.
        return 0

    with open(archive, "rb") as f:
        sha256 = hashlib.sha256()
        while True:
            chunk = f.read(1024 * 1024)
            if not chunk:
                break
            sha256.update(chunk)
        digest = sha256.hexdigest()

    stamp_path = os.path.join(output, ".dawn_archive_digest")
    if os.path.exists(stamp_path):
        with open(stamp_path) as f:
            if f.read().strip() == digest:
                print("Already up-to-date.")
                return 0

    if archive.endswith(".zip"):
        entries = IterateZip(archive)
    elif archive.endswith(".tar.gz"):
        entries = IterateTar(archive, "gz")
    elif archive.endswith(".tar.bz2"):
        entries = IterateTar(archive, "bz2")
    else:
        raise ValueError(archive)

    try:
        if os.path.exists(output):
            print("Removing %s" % (output, ))
            shutil.rmtree(output)

        print("Extracting %s to %s" % (archive, output))
        prefix = None
        num_extracted = 0
        for entry in entries:
            # Even on Windows, zip files must always use forward slashes.
            if "\\" in entry.path or entry.path.startswith("/"):
                raise ValueError(entry.path)

            if not options.no_prefix:
                new_prefix, rest = entry.path.split("/", 1)

                # Ensure the archive is consistent.
                if prefix is None:
                    prefix = new_prefix
                if prefix != new_prefix:
                    raise ValueError((prefix, new_prefix))
            else:
                rest = entry.path

            # Extract the file into the output directory.
            fixed_path = CheckedJoin(output, rest)
            if not os.path.isdir(os.path.dirname(fixed_path)):
                os.makedirs(os.path.dirname(fixed_path))
            if isinstance(entry, FileEntry):
                with open(fixed_path, "wb") as out:
                    shutil.copyfileobj(entry.fileobj, out)
            elif isinstance(entry, SymlinkEntry):
                os.symlink(entry.target, fixed_path)
            else:
                raise TypeError("unknown entry type")

            # Fix up permissions if needbe.
            # TODO(davidben): To be extra tidy, this should only track the execute bit
            # as in git.
            if entry.mode is not None:
                os.chmod(fixed_path, entry.mode)

            # Print every 100 files, so bots do not time out on large archives.
            num_extracted += 1
            if num_extracted % 100 == 0:
                print("Extracted %d files..." % (num_extracted, ))
    finally:
        entries.close()

    with open(stamp_path, "w") as f:
        f.write(digest)

    print("Done. Extracted %d files." % (num_extracted, ))
    return 0


if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
