#!/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.
#
# TODO(sop): Be more detailed: version, link to Maven Central

from __future__ import print_function

import argparse
from collections import defaultdict, deque
from os import chdir, path
import re
from shutil import copyfileobj
from subprocess import Popen, PIPE
from sys import stdout, stderr

parser = argparse.ArgumentParser()
parser.add_argument('--asciidoc', action='store_true')
parser.add_argument('--partial', action='store_true')
parser.add_argument('--classpath', action='append')
parser.add_argument('targets', nargs='+')
args = parser.parse_args()

KNOWN_PROVIDED_DEPS = [
  '//lib/bouncycastle:bcpg',
  '//lib/bouncycastle:bcpkix',
  '//lib/bouncycastle:bcprov',
]

def parse_graph():
  graph = defaultdict(list)
  while not path.isfile('.buckconfig'):
    chdir('..')
  # TODO(davido): use passed in classpath from Buck instead
  p = Popen(
    ['buck', 'audit', 'classpath', '--dot'] + args.targets,
    stdout = PIPE)
  for line in p.stdout:
    m = re.search(r'"(//.*?)" -> "(//.*?)";', line)
    if not m:
      continue
    target, dep = m.group(1), m.group(2)
    if args.partial:
      if dep == '//lib/codemirror:js_minifier':
        if target == '//lib/codemirror:js':
          continue
        if target.startswith('//lib/codemirror:mode_'):
          continue
      if target == '//gerrit-gwtui:ui_module' and \
         dep == '//gerrit-gwtexpui:CSS':
        continue

    # Dependencies included in provided_deps set are contained in audit
    # classpath and must be sorted out. That's safe thing to do because
    # they are not included in the final artifact.
    if "DO_NOT_DISTRIBUTE" in dep:
      if not target in KNOWN_PROVIDED_DEPS:
        print('DO_NOT_DISTRIBUTE license for target: %s' % target, file=stderr)
        exit(1)
    else:
      graph[target].append(dep)
  r = p.wait()
  if r != 0:
    exit(r)
  return graph

graph = parse_graph()
licenses = defaultdict(set)

queue = deque(args.targets)
while queue:
  target = queue.popleft()
  for dep in graph[target]:
    if not dep.startswith('//lib:LICENSE-'):
      continue
    licenses[dep].add(target)
  queue.extend(graph[target])
used = sorted(licenses.keys())

if args.asciidoc:
  print("""\
Gerrit Code Review - Licenses
=============================

Gerrit open source software is licensed under the <<Apache2_0,Apache
License 2.0>>.  Executable distributions also include other software
components that are provided under additional licenses.

[[cryptography]]
Cryptography Notice
-------------------

This distribution includes cryptographic software.  The country
in which you currently reside may have restrictions on the import,
possession, use, and/or re-export to another country, of encryption
software.  BEFORE using any encryption software, please check
your country's laws, regulations and policies concerning the
import, possession, or use, and re-export of encryption software,
to see if this is permitted.  See the
link:http://www.wassenaar.org/[Wassenaar Arrangement]
for more information.

The U.S. Government Department of Commerce, Bureau of Industry
and Security (BIS), has classified this software as Export
Commodity Control Number (ECCN) 5D002.C.1, which includes
information security software using or performing cryptographic
functions with asymmetric algorithms.  The form and manner of
this distribution makes it eligible for export under the License
Exception ENC Technology Software Unrestricted (TSU) exception
(see the BIS Export Administration Regulations, Section 740.13)
for both object code and source code.

Gerrit includes an SSH daemon (Apache SSHD), to support authenticated
uploads of changes directly from `git push` command line clients.

Gerrit includes an SSH client (JSch), to support authenticated
replication of changes to remote systems, such as for automatic
updates of mirror servers, or realtime backups.

For either feature to function, Gerrit requires the
link:http://java.sun.com/javase/technologies/security/[Java Cryptography extensions]
and/or the
link:http://www.bouncycastle.org/java.html[Bouncy Castle Crypto API]
to be installed by the end-user.

Licenses
--------
""")

for n in used:
  libs = sorted(licenses[n])
  name = n[len('//lib:LICENSE-'):]
  if args.asciidoc:
    print()
    print('[[%s]]' % name.replace('.', '_'))
    print(name)
    print('~' * len(name))
    print()
  else:
    print()
    print(name)
    print('--')
  for d in libs:
    if d.startswith('//lib:') or d.startswith('//lib/'):
      p = d[len('//lib:'):]
    else:
      p = d[d.index(':')+1:].lower()
    print('* ' + p)
  if args.asciidoc:
    print()
    print('[[license]]')
    print('[verse]')
    print('--')
  with open(n[2:].replace(':', '/')) as fd:
    copyfileobj(fd, stdout)
  print('--')

if args.asciidoc:
  print("""
GERRIT
------
Part of link:index.html[Gerrit Code Review]
""")
