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

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

MAIN = ['//gerrit-pgm:pgm', '//gerrit-gwtui:ui_module']
KNOWN_PROVIDED_DEPS = [
  '//lib/bouncycastle:bcpg',
  '//lib/bouncycastle:bcpkix',
  '//lib/bouncycastle:bcprov',
]

def parse_graph():
  graph = defaultdict(list)
  while not path.isfile('.buckconfig'):
    chdir('..')
  p = Popen(
    ['buck', 'audit', 'classpath', '--dot'] + MAIN,
    stdout = PIPE)
  for line in p.stdout:
    m = re.search(r'"(//.*?)" -> "(//.*?)";', line)
    if not m:
      continue
    target, dep = m.group(1), m.group(2)
    # 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(MAIN)
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())

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-'):]
  print()
  print('[[%s]]' % name.replace('.', '_'))
  print(name)
  print('~' * len(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)
  print()
  print('[[license]]')
  print('[verse]')
  print('--')
  with open(n[2:].replace(':', '/')) as fd:
    copyfileobj(fd, stdout)
  print('--')

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