#!/usr/bin/env python
# Copyright (C) 2013 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import print_function

import argparse
from hashlib import sha1
from os import link, makedirs, path, remove
import shutil
from subprocess import check_call, CalledProcessError
from sys import stderr
from util import hash_file, resolve_url
from zipfile import ZipFile, BadZipfile, LargeZipFile

GERRIT_HOME = path.expanduser('~/.gerritcodereview')
CACHE_DIR = path.join(GERRIT_HOME, 'bazel-cache', 'downloaded-artifacts')
LOCAL_PROPERTIES = 'local.properties'


def safe_mkdirs(d):
    if path.isdir(d):
        return
    try:
        makedirs(d)
    except OSError as err:
        if not path.isdir(d):
            raise err


def download_properties(root_dir):
    """ Get the download properties.

    First tries to find the properties file in the given root directory,
    and if not found there, tries in the Gerrit settings folder in the
    user's home directory.

    Returns a set of download properties, which may be empty.

    """
    p = {}
    local_prop = path.join(root_dir, LOCAL_PROPERTIES)
    if not path.isfile(local_prop):
        local_prop = path.join(GERRIT_HOME, LOCAL_PROPERTIES)
    if path.isfile(local_prop):
        try:
            with open(local_prop) as fd:
                for line in fd:
                    if line.startswith('download.'):
                        d = [e.strip() for e in line.split('=', 1)]
                        name, url = d[0], d[1]
                        p[name[len('download.'):]] = url
        except OSError:
            pass
    return p


def cache_entry(args):
    if args.v:
        h = args.v
    else:
        h = sha1(args.u.encode('utf-8')).hexdigest()
    name = '%s-%s' % (path.basename(args.o), h)
    return path.join(CACHE_DIR, name)


parser = argparse.ArgumentParser()
parser.add_argument('-o', help='local output file')
parser.add_argument('-u', help='URL to download')
parser.add_argument('-v', help='expected content SHA-1')
parser.add_argument('-x', action='append', help='file to delete from ZIP')
parser.add_argument('--exclude_java_sources', action='store_true')
args = parser.parse_args()

root_dir = args.o
while root_dir and path.dirname(root_dir) != root_dir:
    root_dir, n = path.split(root_dir)
    if n == 'WORKSPACE':
        break

redirects = download_properties(root_dir)
cache_ent = cache_entry(args)
src_url = resolve_url(args.u, redirects)

if not path.exists(cache_ent):
    try:
        safe_mkdirs(path.dirname(cache_ent))
    except OSError as err:
        print('error creating directory %s: %s' %
              (path.dirname(cache_ent), err), file=stderr)
        exit(1)

    print('Download %s' % src_url, file=stderr)
    try:
        check_call(['curl', '--proxy-anyauth', '-ksSfLo', cache_ent, src_url])
    except OSError as err:
        print('could not invoke curl: %s\nis curl installed?' % err,
              file=stderr)
        exit(1)
    except CalledProcessError as err:
        print('error using curl: %s' % err, file=stderr)
        exit(1)

if args.v:
    have = hash_file(sha1(), cache_ent).hexdigest()
    if args.v != have:
        print((
            '%s:\n' +
            'expected %s\n' +
            'received %s\n') % (src_url, args.v, have), file=stderr)
        try:
            remove(cache_ent)
        except OSError as err:
            if path.exists(cache_ent):
                print('error removing %s: %s' % (cache_ent, err), file=stderr)
        exit(1)

exclude = []
if args.x:
    exclude += args.x
if args.exclude_java_sources:
    try:
        with ZipFile(cache_ent, 'r') as zf:
            for n in zf.namelist():
                if n.endswith('.java'):
                    exclude.append(n)
    except (BadZipfile, LargeZipFile) as err:
        print('error opening %s: %s' % (cache_ent, err), file=stderr)
        exit(1)

safe_mkdirs(path.dirname(args.o))
if exclude:
    try:
        shutil.copyfile(cache_ent, args.o)
    except (shutil.Error, IOError) as err:
        print('error copying to %s: %s' % (args.o, err), file=stderr)
        exit(1)
    try:
        check_call(['zip', '-d', args.o] + exclude)
    except CalledProcessError as err:
        print('error removing files from zip: %s' % err, file=stderr)
        exit(1)
else:
    try:
        link(cache_ent, args.o)
    except OSError as err:
        try:
            shutil.copyfile(cache_ent, args.o)
        except (shutil.Error, IOError) as err:
            print('error copying to %s: %s' % (args.o, err), file=stderr)
            exit(1)
