#!/usr/bin/env python2.7
#
# Copyright 2017 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# A script to fetch missing LICENSE files when building a vendored repo

# Should be run from top-level of third_party/rust_crates repository.

import argparse
import os
import re
import sys
import urllib2

repo_re = re.compile('\s*repository\s*=\s*"(.*)"\s*$')

def die(reason):
    raise Exception(reason)

def get_repo_path(subdir):
    for line in open(os.path.join(subdir, 'Cargo.toml')):
        m = repo_re.match(line)
        if m:
            return m.group(1)

def find_github_blob_path(path):
    s = path.split('/')
    if s[2] == 'github.com':
        s[2] = 'raw.githubusercontent.com'
        # github redirects "github.com/$USER/$PROJECT.git" to
        # "github.com/$USER/$PROJECT".
        if s[4].endswith('.git'):
          s[4] = s[4][:len('.git')]
    else:
        die('don\'t know raw content path for ' + path)
    if s[-1] == '':
        del s[-1]
    if len(s) >= 6 and s[5] == 'tree':
        del s[5]
    else:
        s.append('master')
    return '/'.join(s)

def fetch_license(subdir):
    repo_path = get_repo_path(subdir)
    if repo_path is None:
        die('can\'t find repo path for ' + subdir)
    baseurl = find_github_blob_path(repo_path)
    text = []
    # 'LICENCE' is a British English spelling variant used in https://github.com/ebarnard/rust-plist
    for license_filename in ('LICENSE', 'LICENSE-APACHE', 'LICENSE-MIT', 'COPYING', 'LICENCE', 'LICENSE.md'):
        url = '/'.join((baseurl, license_filename))
        try:
            resp = urllib2.urlopen(url)
            contents = resp.read()
            if text: text.append('=' * 40 + '\n')
            text.append(url + ':\n\n')
            text.append(contents)
        except urllib2.HTTPError:
            pass
    if not text:
        die('no licenses found under ' + baseurl)
    else:
        license_out = open(os.path.join(subdir, 'LICENSE'), 'w')
        license_out.write(''.join(text))


def check_licenses(directory, verify=False):
    success = True
    os.chdir(directory)
    for subdir in sorted(os.listdir(os.getcwd())):
        # TODO(pylaligand): remove this temporary hack when a new version of
        # the crate is published.
        if (subdir.startswith('magenta-sys') or
                subdir.startswith('fuchsia-zircon-sys')):
            print 'IGNORED  %s' % subdir
            continue
        if subdir.startswith('.') or not os.path.isdir(subdir):
            continue
        license_files = [file for file in os.listdir(subdir)
                         if file.startswith('LICENSE') or
                         file.startswith('LICENCE') or
                         file.startswith('license')]
        if license_files:
            print 'OK       %s' % subdir
            continue
        if verify:
            print 'MISSING  %s' % subdir
            success = False
            continue
        try:
            fetch_license(subdir)
            print 'FETCH    %s' % subdir
        except Exception as err:
            print 'ERROR    %s (%s)' % (subdir, err.message)
            success = False
    return success


def main():
    parser = argparse.ArgumentParser(
        'Verifies licenses for third-party Rust crates')
    parser.add_argument('--directory',
                        help='Directory containing the crates',
                        default=os.getcwd())
    parser.add_argument('--verify',
                        help='Simply check whether licenses are up-to-date',
                        action='store_true')
    args = parser.parse_args()
    if not check_licenses(args.directory, verify=args.verify):
        sys.exit(1)


if __name__ == '__main__':
    main()
