#!/usr/bin/env python
# Copyright (C) 2015 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
import hashlib
import json
import os
import shutil
import subprocess
import sys

import bowerutil

CACHE_DIR = os.environ.get(
    'GERRIT_CACHE_HOME',
    os.path.expanduser(os.path.join(
        '~', '.gerritcodereview', 'bazel-cache', 'downloaded-artifacts'
    ))
)


def bower_cmd(bower, *args):
    cmd = bower.split(' ')
    cmd.extend(args)
    return cmd


def bower_info(bower, name, package, version):
    cmd = bower_cmd(bower, '-l=error', '-j',
                    'info', '%s#%s' % (package, version))
    try:
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
    except:
        sys.stderr.write("error executing: %s\n" % ' '.join(cmd))
        raise
    out, err = p.communicate()
    if p.returncode:
        # For python3 support we wrap str around err.
        sys.stderr.write(str(err))
        raise OSError('Command failed: %s' % ' '.join(cmd))

    try:
        info = json.loads(out)
    except ValueError:
        raise ValueError('invalid JSON from %s:\n%s' % (" ".join(cmd), out))
    info_name = info.get('name')
    if info_name != name:
        raise ValueError(
            'expected package name %s, got: %s' % (name, info_name))
    return info


def ignore_deps(info):
    # Tell bower to ignore dependencies so we just download this component.
    # This is just an optimization, since we only pick out the component we
    # need, but it's important when downloading sizable dependency trees.
    #
    # As of 1.6.5 I don't think ignoredDependencies can be specified on the
    # command line with --config, so we have to create .bowerrc.
    deps = info.get('dependencies')
    if deps:
        with open(os.path.join('.bowerrc'), 'w') as f:
            json.dump({'ignoredDependencies': list(deps.keys())}, f)


def cache_entry(name, package, version, sha1):
    if not sha1:
        sha1 = hashlib.sha1('%s#%s' % (package, version)).hexdigest()
    return os.path.join(CACHE_DIR, '%s-%s.zip-%s' % (name, version, sha1))


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-n', help='short name of component')
    parser.add_argument('-b', help='bower command')
    parser.add_argument('-p', help='full package name of component')
    parser.add_argument('-v', help='version number')
    parser.add_argument('-s', help='expected content sha1')
    parser.add_argument('-o', help='output file location')
    args = parser.parse_args()

    assert args.p
    assert args.v
    assert args.n

    cwd = os.getcwd()
    outzip = os.path.join(cwd, args.o)
    cached = cache_entry(args.n, args.p, args.v, args.s)

    if not os.path.exists(cached):
        info = bower_info(args.b, args.n, args.p, args.v)
        ignore_deps(info)
        subprocess.check_call(
            bower_cmd(
                args.b, '--quiet', 'install', '%s#%s' % (args.p, args.v)))
        bc = os.path.join(cwd, 'bower_components')
        subprocess.check_call(
            ['zip', '-q', '--exclude', '.bower.json', '-r', cached, args.n],
            cwd=bc)

        if args.s:
            path = os.path.join(bc, args.n)
            sha1 = bowerutil.hash_bower_component(
                hashlib.sha1(), path).hexdigest()
            if args.s != sha1:
                print((
                    '%s#%s:\n'
                    'expected %s\n'
                    'received %s\n') % (args.p, args.v, args.s, sha1),
                    file=sys.stderr)
                try:
                    os.remove(cached)
                except OSError as err:
                    if path.exists(cached):
                        print('error removing %s: %s' % (cached, err),
                              file=sys.stderr)
                return 1

    shutil.copyfile(cached, outzip)
    return 0


if __name__ == '__main__':
    sys.exit(main())
