#!/usr/bin/env python3
# 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 environ, 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 = environ.get(
    'GERRIT_CACHE_HOME',
    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)
