#!/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

from hashlib import sha1
from optparse import OptionParser
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)


opts = OptionParser()
opts.add_option('-o', help='local output file')
opts.add_option('-u', help='URL to download')
opts.add_option('-v', help='expected content SHA-1')
opts.add_option('-x', action='append', help='file to delete from ZIP')
opts.add_option('--exclude_java_sources', action='store_true')
opts.add_option('--unsign', action='store_true')
args, _ = opts.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)

if args.unsign:
    try:
        with ZipFile(cache_ent, 'r') as zf:
            for n in zf.namelist():
                if (n.endswith('.RSA')
                   or n.endswith('.SF')
                   or n.endswith('.LIST')):
                    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)
