#!/usr/bin/python -u

"""
Utility to upload or remove the packages from the packages repository.
"""

import logging, optparse, os, shutil, sys, tempfile
import common
from autotest_lib.client.common_lib import utils as client_utils
from autotest_lib.client.common_lib import global_config, error
from autotest_lib.client.common_lib import packages
from autotest_lib.server import utils as server_utils

c = global_config.global_config
logging.basicConfig(level=logging.DEBUG)

def get_exclude_string(client_dir):
    '''
    Get the exclude string for the tar command to exclude specific
    subdirectories inside client_dir.
    For profilers we need to exclude everything except the __init__.py
    file so that the profilers can be imported.
    '''
    exclude_string = ('--exclude=deps/* --exclude=tests/* '
                      '--exclude=site_tests/* --exclude=**.pyc')

    # Get the profilers directory
    prof_dir = os.path.join(client_dir, 'profilers')

    # Include the __init__.py file for the profilers and exclude all its
    # subdirectories
    for f in os.listdir(prof_dir):
        if os.path.isdir(os.path.join(prof_dir, f)):
            exclude_string += ' --exclude=profilers/%s' % f

    # The '.' here is needed to zip the files in the current
    # directory. We use '-C' for tar to change to the required
    # directory i.e. src_dir and then zip up the files in that
    # directory(which is '.') excluding the ones in the exclude_dirs
    exclude_string += " ."

    # TODO(milleral): This is sad and ugly.  http://crbug.com/258161
    # Surprisingly, |exclude_string| actually means argument list, and
    # we'd like to package up the current global_config.ini also, so let's
    # just tack it on here.
    # Also note that this only works because tar prevents us from un-tarring
    # files into parent directories.
    exclude_string += " ../global_config.ini"

    return exclude_string


def parse_args():
    parser = optparse.OptionParser()
    parser.add_option("-d", "--dependency", help="package the dependency"
                      " from client/deps directory and upload to the repo",
                      dest="dep")
    parser.add_option("-p", "--profiler", help="package the profiler "
                      "from client/profilers directory and upload to the repo",
                      dest="prof")
    parser.add_option("-t", "--test", help="package the test from client/tests"
                      " or client/site_tests and upload to the repo.",
                      dest="test")
    parser.add_option("-c", "--client", help="package the client "
                      "directory alone without the tests, deps and profilers",
                      dest="client", action="store_true", default=False)
    parser.add_option("-f", "--file", help="simply uploads the specified"
                      "file on to the repo", dest="file")
    parser.add_option("-r", "--repository", help="the URL of the packages"
                      "repository location to upload the packages to.",
                      dest="repo", default=None)
    parser.add_option("--all", help="Upload all the files locally "
                      "to all the repos specified in global_config.ini. "
                      "(includes the client, tests, deps and profilers)",
                      dest="all", action="store_true", default=False)

    options, args = parser.parse_args()
    return options, args


# Method to upload or remove package depending on the flag passed to it.
def process_packages(pkgmgr, pkg_type, pkg_names, src_dir,
                    remove=False):
    exclude_string = ' .'
    names = [p.strip() for p in pkg_names.split(',')]
    for name in names:
        print "Processing %s ... " % name
        if pkg_type == 'client':
            pkg_dir = src_dir
            exclude_string = get_exclude_string(pkg_dir)
        elif pkg_type == 'test':
            # if the package is a test then look whether it is in client/tests
            # or client/site_tests
            pkg_dir = os.path.join(get_test_dir(name, src_dir), name)
        else:
            # for the profilers and deps
            pkg_dir = os.path.join(src_dir, name)

        pkg_name = pkgmgr.get_tarball_name(name, pkg_type)
        if not remove:
            # Tar the source and upload
            temp_dir = tempfile.mkdtemp()
            try:
                try:
                    packages.check_diskspace(temp_dir)
                except error.RepoDiskFullError, e:
                    msg = ("Temporary directory for packages %s does not have "
                           "enough space available: %s" % (temp_dir, e))
                    raise error.RepoDiskFullError(msg)
                tarball_path = pkgmgr.tar_package(pkg_name, pkg_dir,
                                                  temp_dir, exclude_string)
                pkgmgr.upload_pkg(tarball_path, update_checksum=True)
            finally:
                # remove the temporary directory
                shutil.rmtree(temp_dir)
        else:
            pkgmgr.remove_pkg(pkg_name, remove_checksum=True)
        print "Done."


def tar_packages(pkgmgr, pkg_type, pkg_names, src_dir, temp_dir):
    """Tar all packages up and return a list of each tar created"""
    tarballs = []
    exclude_string = ' .'
    names = [p.strip() for p in pkg_names.split(',')]
    for name in names:
        print "Processing %s ... " % name
        if pkg_type == 'client':
            pkg_dir = src_dir
            exclude_string = get_exclude_string(pkg_dir)
        elif pkg_type == 'test':
            # if the package is a test then look whether it is in client/tests
            # or client/site_tests
            pkg_dir = os.path.join(get_test_dir(name, src_dir), name)
        else:
            # for the profilers and deps
            pkg_dir = os.path.join(src_dir, name)

        pkg_name = pkgmgr.get_tarball_name(name, pkg_type)
        tarball_path = pkgmgr.tar_package(pkg_name, pkg_dir,
                                              temp_dir, exclude_string)

        tarballs.append(tarball_path)
    return tarballs


def process_all_packages(pkgmgr, client_dir, remove=False):
    """Process a full upload of packages as a directory upload."""
    dep_dir = os.path.join(client_dir, "deps")
    prof_dir = os.path.join(client_dir, "profilers")
    # Directory where all are kept
    temp_dir = tempfile.mkdtemp()
    try:
        packages.check_diskspace(temp_dir)
    except error.RepoDiskFullError, e:
        print ("Temp destination for packages is full %s, aborting upload: %s"
               % (temp_dir, e))
        os.rmdir(temp_dir)
        sys.exit(1)

    # process tests
    tests_list = get_subdir_list('tests', client_dir)
    tests = ','.join(tests_list)

    # process site_tests
    site_tests_list = get_subdir_list('site_tests', client_dir)
    site_tests = ','.join(site_tests_list)

    # process deps
    deps_list = get_subdir_list('deps', client_dir)
    deps = ','.join(deps_list)

    # process profilers
    profilers_list = get_subdir_list('profilers', client_dir)
    profilers = ','.join(profilers_list)

    # Update md5sum
    if not remove:
        all_packages = []
        all_packages.extend(tar_packages(pkgmgr, 'profiler', profilers,
                                         prof_dir, temp_dir))
        all_packages.extend(tar_packages(pkgmgr, 'dep', deps, dep_dir,
                                         temp_dir))
        all_packages.extend(tar_packages(pkgmgr, 'test', site_tests,
                                         client_dir, temp_dir))
        all_packages.extend(tar_packages(pkgmgr, 'test', tests, client_dir,
                                         temp_dir))
        all_packages.extend(tar_packages(pkgmgr, 'client', 'autotest',
                                         client_dir, temp_dir))
        for package in all_packages:
            pkgmgr.upload_pkg(package, update_checksum=True)
        client_utils.run('rm -rf ' + temp_dir)
    else:
        process_packages(pkgmgr, 'test', tests, client_dir, remove=remove)
        process_packages(pkgmgr, 'test', site_tests, client_dir, remove=remove)
        process_packages(pkgmgr, 'client', 'autotest', client_dir,
                         remove=remove)
        process_packages(pkgmgr, 'dep', deps, dep_dir, remove=remove)
        process_packages(pkgmgr, 'profiler', profilers, prof_dir,
                         remove=remove)


# Get the list of sub directories present in a directory
def get_subdir_list(name, client_dir):
    dir_name = os.path.join(client_dir, name)
    return [f for f in
            os.listdir(dir_name)
            if os.path.isdir(os.path.join(dir_name, f)) ]


# Look whether the test is present in client/tests and client/site_tests dirs
def get_test_dir(name, client_dir):
    names_test = os.listdir(os.path.join(client_dir, 'tests'))
    names_site_test = os.listdir(os.path.join(client_dir, 'site_tests'))
    if name in names_test:
        src_dir = os.path.join(client_dir, 'tests')
    elif name in names_site_test:
        src_dir = os.path.join(client_dir, 'site_tests')
    else:
        print "Test %s not found" % name
        sys.exit(0)
    return src_dir


def main():
    # get options and args
    options, args = parse_args()

    server_dir = server_utils.get_server_dir()
    autotest_dir = os.path.abspath(os.path.join(server_dir, '..'))

    # extract the pkg locations from global config
    repo_urls = c.get_config_value('PACKAGES', 'fetch_location',
                                   type=list, default=[])
    upload_paths = c.get_config_value('PACKAGES', 'upload_location',
                                      type=list, default=[])

    if options.repo:
        upload_paths.append(options.repo)

    # Having no upload paths basically means you're not using packaging.
    if not upload_paths:
        print("No upload locations found. Please set upload_location under"
              " PACKAGES in the global_config.ini or provide a location using"
              " the --repository option.")
        return

    client_dir = os.path.join(autotest_dir, "client")

    # Bail out if the client directory does not exist
    if not os.path.exists(client_dir):
        sys.exit(0)

    dep_dir = os.path.join(client_dir, "deps")
    prof_dir = os.path.join(client_dir, "profilers")

    if len(args) == 0 or args[0] not in ['upload', 'remove']:
        print("Either 'upload' or 'remove' needs to be specified "
              "for the package")
        sys.exit(0)

    if args[0] == 'upload':
        remove_flag = False
    elif args[0] == 'remove':
        remove_flag = True
    else:
        # we should not be getting here
        assert(False)

    pkgmgr = packages.PackageManager(autotest_dir, repo_urls=repo_urls,
                                     upload_paths=upload_paths,
                                     run_function_dargs={'timeout':600})

    if options.all:
        process_all_packages(pkgmgr, client_dir, remove=remove_flag)

    if options.client:
        process_packages(pkgmgr, 'client', 'autotest', client_dir,
                         remove=remove_flag)

    if options.dep:
        process_packages(pkgmgr, 'dep', options.dep, dep_dir,
                         remove=remove_flag)

    if options.test:
        process_packages(pkgmgr, 'test', options.test, client_dir,
                         remove=remove_flag)

    if options.prof:
        process_packages(pkgmgr, 'profiler', options.prof, prof_dir,
                         remove=remove_flag)

    if options.file:
        if remove_flag:
            pkgmgr.remove_pkg(options.file, remove_checksum=True)
        else:
            pkgmgr.upload_pkg(options.file, update_checksum=True)


if __name__ == "__main__":
    main()
