#!/usr/bin/env python3
# Copyright (C) 2017 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 os
import subprocess
import re
import sys
import xml.dom.minidom

JRE = '/'.join([
  'org.eclipse.jdt.launching.JRE_CONTAINER',
  'org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType',
  'JavaSE-11',
])

class EclipseProject():

  # Path to the Bazel/Bazelisk binary
  bazel_exe = None
  # Root of the Bazel project (holding WORKSPACE file)
  ROOT = None

  def main(self):
    self.bazel_exe = self.find_bazel(self.args.bazel_exe)

    self.ROOT = self.find_root(self.args.root)

    project_name = (self.args.name if self.args.name
                    else os.path.basename(self.ROOT))

    self.gen_project(project_name, root=self.ROOT)
    self.gen_classpath(self.retrieve_ext_location().decode('utf-8'))

  def _get_argument_parser(self):
    opts = argparse.ArgumentParser("Create Eclipse Project")
    opts.add_argument('-r', '--root', help='Root directory entry',
                      required=True)
    opts.add_argument('-n', '--name', help='Project name')
    opts.add_argument('-x', '--exclude', action='append', help='Exclude paths')
    opts.add_argument('-b', '--batch', action='store_true',
                      dest='batch', help='Bazel batch option')
    opts.add_argument('--bazel',
                      help=('name of the bazel executable. Defaults to using'
                            ' bazelisk if found, or bazel if bazelisk is not'
                            ' found.'),
                      action='store', default=None, dest='bazel_exe')
    return opts

  def parse_args(self, args):
    self.args = self._get_argument_parser().parse_args(args)
    return self.args

  def find_root(self, root):
    ROOT = os.path.abspath(root)
    while not os.path.exists(os.path.join(ROOT, 'WORKSPACE')):
      if ROOT == '/':
        raise Exception(
          'Could not find root of project: no WORKSPACE file found')
      ROOT = os.path.dirname(ROOT)
    return ROOT

  def find_bazel(self, bazel_exe=None):
    if bazel_exe:
      try:
        return subprocess.check_output(
          ['which', bazel_exe]).strip().decode('UTF-8')
      except subprocess.CalledProcessError:
        raise Exception('Bazel command: %s not found' % bazel_exe)
    try:
      return subprocess.check_output(
        ['which', 'bazelisk']).strip().decode('UTF-8')
    except subprocess.CalledProcessError:
      try:
        return subprocess.check_output(
          ['which', 'bazel']).strip().decode('UTF-8')
      except subprocess.CalledProcessError:
        raise Exception(
          "Neither bazelisk nor bazel found. Please see"
          " Documentation/dev-bazel for instructions on installing"
          " one of them.")

  def _build_bazel_cmd(self, *args):
    cmd = [self.bazel_exe]
    if self.args.batch:
      cmd.append('--batch')
    for arg in args:
      cmd.append(arg)
    return cmd

  def retrieve_ext_location(self):
    return subprocess.check_output(
      self._build_bazel_cmd('info', 'output_base')).strip()

  def _query_classpath(self):
    t = '//tools/eclipse:main_classpath_collect'
    try:
      cmd = self._build_bazel_cmd('build', t)
      subprocess.check_call(cmd)
    except subprocess.CalledProcessError:
      raise Exception("Could not query classpath with:" % cmd)
    name = 'bazel-bin/tools/eclipse/' + t.split(':')[1] + '.runtime_classpath'
    return [line.rstrip('\n') for line in open(name)]

  def gen_project(self, name, root):
    p = os.path.join(root, '.project')
    with open(p, 'w') as fd:
      print("""\
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
  <name>%(name)s</name>
  <buildSpec>
    <buildCommand>
      <name>org.eclipse.jdt.core.javabuilder</name>
    </buildCommand>
  </buildSpec>
  <natures>
    <nature>org.eclipse.jdt.core.javanature</nature>
  </natures>
</projectDescription>\
    """ % {"name": name}, file=fd)

  def gen_classpath(self, ext):
    def make_classpath():
      impl = xml.dom.minidom.getDOMImplementation()
      return impl.createDocument(None, 'classpath', None)

    def classpathentry(kind, path, src=None, out=None, exported=None):
      e = doc.createElement('classpathentry')
      e.setAttribute('kind', kind)
      # TODO(davido): Remove this and other exclude BUILD files hack
      # when this Bazel bug is fixed:
      # https://github.com/bazelbuild/bazel/issues/1083
      if kind == 'src':
        e.setAttribute('excluding', '**/BUILD')
      e.setAttribute('path', path)
      if src:
        e.setAttribute('sourcepath', src)
      if out:
        e.setAttribute('output', out)
      if exported:
        e.setAttribute('exported', 'true')
      doc.documentElement.appendChild(e)

    doc = make_classpath()
    src = set()
    lib = set()
    rule_jvm_externals = set()

    rule_jvm_external = re.compile('bazel-out/.*?-fastbuild/bin/external/maven/(.*[.]jar)$')
    java_library = re.compile('bazel-out/(?:.*)-fastbuild/bin(.*)/[^/]+[.]jar$')
    srcs = re.compile('(.*/external/[^/]+)/jar/(.*)[.]jar')
    for p in self._query_classpath():

      m = rule_jvm_external.match(p)
      if m and ext is not None:
        p = os.path.join(ext, 'external/unpinned_maven', m.group(1))
        rule_jvm_externals.add(p)
        continue

      m = java_library.match(p)
      if m:
        src.add(m.group(1).lstrip('/'))
      else:
        if ext is not None and p.startswith("external"):
          p = os.path.join(ext, p)
          lib.add(p)

    src_paths = {}
    for s in sorted(src):
      out = None

      if s.startswith('lib/'):
        out = 'eclipse-out/lib'

      p = os.path.join(s, 'java')
      if os.path.exists(p):
        classpathentry('src', p, out=out)
        continue

      for env in ['main', 'test', 'java', 'javatests']:
        o = None
        if out:
          o = out + '/' + env
        elif env == 'test' or env == 'javatests':
          o = 'eclipse-out/test'

        if s.startswith(env + '/'):
          src_paths[env] = o
          continue

        for srctype in ['java', 'resources']:
          p = os.path.join(s, 'src', env, srctype)
          if os.path.exists(p):
            src_paths[p] = o

    for s in src_paths:
      classpathentry('src', s, out=src_paths[s])

    for libs in [lib]:
      for j in sorted(libs):
        if self.excluded(j):
          continue
        s = None
        m = srcs.match(j)
        if m:
          prefix = m.group(1)
          suffix = m.group(2)
          p = os.path.join(prefix, "src", "%s-src.jar" % suffix)
          if os.path.exists(p):
            s = p
        classpathentry('lib', j, s)

    for r in sorted(rule_jvm_externals):
      s = r.replace('.jar', '-sources.jar')
      classpathentry('lib', r, s)

    classpathentry('con', JRE)
    classpathentry('output', 'eclipse-out/classes')

    p = os.path.join(self.ROOT, '.classpath')
    with open(p, 'w') as fd:
      doc.writexml(fd, addindent='\t', newl='\n', encoding='UTF-8')

  def excluded(self, lib):
    if self.args.exclude:
      for x in self.args.exclude:
        if x in lib:
          return True
    return False

def main():
  try:
    ec = EclipseProject()
    ec.parse_args(args=sys.argv[1:])
    ec.main()
  except KeyboardInterrupt:
    print('Interrupted by user', file=sys.stderr)
    exit(1)


if __name__ == '__main__':
  main()
