#!/usr/bin/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): Remove hack after Buck supports Eclipse

from __future__ import print_function
from optparse import OptionParser
from os import path
from subprocess import Popen, PIPE, CalledProcessError, check_call
from xml.dom import minidom
import re
import sys

MAIN = ['//tools/eclipse:classpath']
GWT = ['//gerrit-gwtui:ui_module']
JRE = '/'.join([
  'org.eclipse.jdt.launching.JRE_CONTAINER',
  'org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType',
  'JavaSE-1.7',
])

ROOT = path.abspath(__file__)
while not path.exists(path.join(ROOT, '.buckconfig')):
  ROOT = path.dirname(ROOT)

opts = OptionParser()
opts.add_option('--src', action='store_true')
opts.add_option('--plugins', help='create eclipse projects for plugins',
                action='store_true')
args, _ = opts.parse_args()

def _query_classpath(targets):
  deps = []
  p = Popen(['buck', 'audit', 'classpath'] + targets, stdout=PIPE)
  for line in p.stdout:
    deps.append(line.strip())
  s = p.wait()
  if s != 0:
    exit(s)
  return deps


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

def gen_plugin_classpath(root):
  p = path.join(root, '.classpath')
  with open(p, 'w') as fd:
    if path.exists(path.join(root, 'src', 'test', 'java')):
      testpath = """
  <classpathentry kind="src" path="src/test/java"\
 out="buck-out/eclipse/test"/>"""
    else:
      testpath = ""
    print("""\
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
  <classpathentry kind="src" path="src/main/java"/>%(testpath)s
  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
  <classpathentry combineaccessrules="false" kind="src" path="/gerrit"/>
  <classpathentry kind="output" path="buck-out/eclipse/classes"/>
</classpath>""" % {"testpath": testpath}, file=fd)

def gen_classpath():
  def make_classpath():
    impl = 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)
    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()
  gwt_src = set()
  gwt_lib = set()
  plugins = set()

  java_library = re.compile(r'[^/]+/gen/(.*)/lib__[^/]+__output/[^/]+[.]jar$')
  for p in _query_classpath(MAIN):
    if p.endswith('-src.jar'):
      # gwt_module() depends on -src.jar for Java to JavaScript compiles.
      gwt_lib.add(p)
      continue

    if p.startswith('buck-out/gen/lib/gwt/'):
      # gwt_module() depends on huge shaded GWT JARs that import
      # incorrect versions of classes for Gerrit. Collect into
      # a private grouping for later use.
      gwt_lib.add(p)
      continue

    m = java_library.match(p)
    if m:
      src.add(m.group(1))
    else:
      lib.add(p)

  for p in _query_classpath(GWT):
    m = java_library.match(p)
    if m:
      gwt_src.add(m.group(1))

  for s in sorted(src):
    out = None

    if s.startswith('lib/'):
      out = 'buck-out/eclipse/lib'
    elif s.startswith('plugins/'):
      if args.plugins:
        plugins.add(s)
        continue
      out = 'buck-out/eclipse/' + s

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

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

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

  for libs in [gwt_lib, lib]:
    for j in sorted(libs):
      s = None
      if j.endswith('.jar'):
        s = j[:-4] + '-src.jar'
        if not path.exists(s):
          s = None
      if args.plugins:
        classpathentry('lib', j, s, exported=True)
      else:
        classpathentry('lib', j, s)
  for s in sorted(gwt_src):
    p = path.join(ROOT, s, 'src', 'main', 'java')
    classpathentry('lib', p, out='buck-out/eclipse/gwtsrc')

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

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

  if args.plugins:
    for plugin in plugins:
      plugindir = path.join(ROOT, plugin)
      try:
        gen_project(plugin.replace('plugins/', ""), plugindir)
        gen_plugin_classpath(plugindir)
      except (IOError, OSError) as err:
        print('error generating project for %s: %s' % (plugin, err),
              file=sys.stderr)

def gen_factorypath():
  doc = minidom.getDOMImplementation().createDocument(None, 'factorypath', None)
  for jar in _query_classpath(['//lib/auto:auto-value']):
    e = doc.createElement('factorypathentry')
    e.setAttribute('kind', 'EXTJAR')
    e.setAttribute('id', path.join(ROOT, jar))
    e.setAttribute('enabled', 'true')
    e.setAttribute('runInBatchMode', 'false')
    doc.documentElement.appendChild(e)

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

try:
  if args.src:
    try:
      check_call([path.join(ROOT, 'tools', 'download_all.py'), '--src'])
    except CalledProcessError as err:
      exit(1)

  gen_project()
  gen_classpath()
  gen_factorypath()

  try:
    targets = ['//tools:buck.properties'] + MAIN + GWT
    check_call(['buck', 'build'] + targets)
  except CalledProcessError as err:
    exit(1)
except KeyboardInterrupt:
  print('Interrupted by user', file=sys.stderr)
  exit(1)
