#!/usr/bin/env python3
# Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import argparse
import gradle
import fnmatch
import os
import re
import sys
import utils
import xml.etree.ElementTree as ET

CLOUD_LOCATION = 'gs://r8-deps/maven_mirror'

GRADLE_CACHE = os.path.join(utils.USER_HOME, '.gradle', 'caches')

def parse_arguments():
  parser = argparse.ArgumentParser()
  parser.add_argument('--check_mirror',
      help = 'Checks that all dependencies are  mirrored, '
          'returns non-zero if not.',
      default = False,
      action = 'store_true')
  return parser.parse_args()


def xml_get(element, tag):
  # The tags are prefixed with like: {http://maven.apache.org/POM/4.0.0}parent
  for child in element.iter():
    if child.tag.endswith(tag):
      yield child

def xml_get_single(element, tag):
  elements = list(xml_get(element, tag))
  if len(elements) == 0:
    return None
  assert len(elements) == 1
  return elements[0]

def find_pom_in_gradle_cache(pom, cached_poms):
  cached = [p for p in cached_poms if p.endswith(pom)]
  assert len(cached) == 1, 'did not find %s in %s' % (pom, cached_poms)
  return cached[0]

# This is a hack, gradle does not provide access to parent poms, which
# we need to mirror.
def get_parent(pom_file, gradle_cached_poms):
  tree = ET.parse(pom_file)
  root = tree.getroot()
  ns = {'pom': 'http://maven.apache.org/POM/4.0.0' }
  parent = root.find('pom:parent', ns)
  if parent is not None:
    group = parent.find('pom:groupId', ns).text
    artifact = parent.find('pom:artifactId', ns).text
    version = parent.find('pom:version', ns).text
    filename = '%s-%s.pom' % (artifact, version)
    parent_path = find_pom_in_gradle_cache(filename, gradle_cached_poms)
    return Entry(group, artifact, version, parent_path)

# Returns a tuple: (group, artifact, version)
def parse_descriptor(descriptor):
  # Descriptor like org.ow2.asm:asm:6.2.1
  split = descriptor.split(':')
  return (split[0], split[1], split[2])

class Entry(object):
  def __init__(self, group, artifact, version, path):
    self.group = group
    self.artifact = artifact
    self.version = version
    self.path = path
    assert os.path.exists(self.path)
    self.jar = None

  def set_jar(self, jar):
    self.jar = jar
    assert os.path.exists(jar)

  def get_cloud_dir(self):
    return os.path.join(CLOUD_LOCATION, '/'.join(self.group.split('.')))

  def get_name(self):
    return '%s-%s' % (self.artifact, self.version)

  def get_cloud_destination(self):
    return os.path.join(self.get_cloud_dir(), self.artifact, self.version,
                        self.get_name())

  def get_cloud_jar_location(self):
    assert self.jar is not None
    suffix = self.jar[len(self.jar)-4:]
    return self.get_cloud_destination() + suffix

  def get_cloud_pom_location(self):
    return self.get_cloud_destination() + '.pom'

def read_gradle_cache_pom_files():
  pom_files = []
  for root, dirnames, filenames in os.walk(GRADLE_CACHE):
    for filename in fnmatch.filter(filenames, '*.pom'):
      pom_files.append(os.path.join(root, filename))
  return pom_files

# We set the name to be group:artifact:version, same as gradle prints
def get_descriptor_from_path(entry):
  # Example
  # /usr.../org.ow2.asm/asm/6.2.1/3bc91be104d9292ff1dcc3dbf1002b7c320e767d/asm-6.2.1.pom
  basename = os.path.basename(entry)
  dirname = os.path.dirname(os.path.dirname(entry))
  version = os.path.basename(dirname)
  dirname = os.path.dirname(dirname)
  artifact = os.path.basename(dirname)
  dirname = os.path.dirname(dirname)
  group = os.path.basename(dirname)
  # Sanity, filename is artifact-version.{pom,jar}
  assert '%s-%s' % (artifact, version) == basename[0:len(basename)-4]
  return '%s:%s:%s' % (group, artifact, version)

def Main():
  args = parse_arguments()
  # Ensure that everything is downloaded before generating the pom list
  gradle.RunGradle(['-stop'])
  gradle_deps = gradle.RunGradleGetOutput(
      ['printMavenDeps', '-Pupdatemavendeps']).splitlines()
  gradle_poms = read_gradle_cache_pom_files()

  # Example output lines:
  # POM: /usr.../org.ow2.asm/asm/6.2.1/3bc91be104d9292ff1dcc3dbf1002b7c320e767d/asm-6.2.1.pom org.ow2.asm:asm:6.2.1
  # JAR: /usr.../com.google.code.gson/gson/2.7/751f548c85fa49f330cecbb1875893f971b33c4e/gson-2.7.jar
  poms = [l[5:] for l in gradle_deps if l.startswith('POM: ')]
  jars = [l[5:] for l in gradle_deps if l.startswith('JAR: ')]
  descriptor_to_entry = {}
  parents = []
  for pom in poms:
    split = pom.split(' ')
    filepath = split[0]
    gradle_descriptor = split[1]
    descriptor = get_descriptor_from_path(filepath)
    assert descriptor == gradle_descriptor
    (group, artifact, version) = parse_descriptor(gradle_descriptor)
    descriptor_to_entry[descriptor] = Entry(group, artifact, version, filepath)
    parent = get_parent(filepath, gradle_poms)
    while parent:
      descriptor = get_descriptor_from_path(parent.path)
      descriptor_to_entry[descriptor] = parent
      parent = get_parent(parent.path, gradle_poms)
  for jar in jars:
    if jar.startswith(utils.REPO_ROOT):
      continue
    descriptor = get_descriptor_from_path(jar)
    assert descriptor in descriptor_to_entry
    descriptor_to_entry[descriptor].set_jar(jar)
  has_missing = False
  for descriptor in descriptor_to_entry:
    entry = descriptor_to_entry[descriptor]
    if not utils.file_exists_on_cloud_storage(entry.get_cloud_pom_location()):
      if args.check_mirror:
        has_missing = True
        print 'Missing dependency for: ' + descriptor
      else:
        print 'Uploading: %s' % entry.path
        utils.upload_file_to_cloud_storage(entry.path, entry.get_cloud_pom_location())
    if entry.jar:
      if not utils.file_exists_on_cloud_storage(entry.get_cloud_jar_location()):
        if args.check_mirror:
          has_missing = True
          print 'Missing dependency for: ' + descriptor
        else:
          print 'Uploading: %s' % entry.jar
          utils.upload_file_to_cloud_storage(entry.jar, entry.get_cloud_jar_location())

  if args.check_mirror:
    if has_missing:
      print('The maven mirror has missing dependencies, please run'
            'tools/maven_mirror.py')
      return 1
    else:
      print('Mirror is up to date with all dependencies')

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