#!/usr/bin/env python
# Copyright (C) 2015 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
from optparse import OptionParser
from os import path, walk
from subprocess import check_output
import re


def guess_maven_group_id(plugin_name, plugin_dir):
  current_dir = None
  for dir_path, dirs, files in walk(path.join(plugin_dir, 'src', 'main', 'java')):
    if len(files) > 0 or len(dirs) > 1 or path.basename(dir_path) == plugin_name:
      break
    current_dir = dir_path

  if current_dir is None:
    return str(hash(plugin_name))

  group_id = []
  while not path.basename(current_dir) == 'java':
    group_id.append(path.basename(current_dir))
    current_dir = path.dirname(current_dir)
  return '.'.join(reversed(group_id))


def get_plugin_version(plugin_dir):
  version = '1.0'
  version_file_path = path.join(plugin_dir, 'VERSION')
  if path.exists(version_file_path):
    try:
      with open(version_file_path, "r") as version_file:
        data = re.sub(r"\s+", '', version_file.read())
    except Exception as err:
      print('error reading plugin version: %s' % err)
    else:
      match = re.search(r"PLUGIN_VERSION='(.*?)'", data)
      if match:
        version = match.group(1)
  elif path.exists(path.join(plugin_dir, '.git')):
    version = check_output(['git', 'describe', '--always', 'HEAD'],
                           cwd=plugin_dir)
  return version


def generate_project_properties(plugin_name, plugin_dir, classes_dir, test_dir,
                                output):
  try:
    with open(output, 'w') as fd:
      print("""\
sonar.projectKey=%s
sonar.projectName=%s
sonar.projectVersion=%s

sonar.language=java
sonar.sources=%s
sonar.tests=%s
sonar.sourceEncoding=UTF-8
sonar.java.binaries=%s

sonar.junit.reportsPath=%s
sonar.core.codeCoveragePlugin=jacoco
sonar.jacoco.reportPath=%s\
""" % (guess_maven_group_id(plugin_name, plugin_dir) + ":" + plugin_name,
       plugin_name,
       get_plugin_version(plugin_dir),
       path.join(plugin_dir, 'src', 'main', 'java'),
       path.join(plugin_dir, 'src', 'test', 'java'),
       classes_dir,
       test_dir,
       path.join(plugin_dir, 'buck-out', 'gen', 'jacoco', 'jacoco.exec')),
            file=fd)
  except Exception as err:
      print('error writing project properties file: %s' % err)


if __name__ == '__main__':
  opts = OptionParser()
  opts.add_option('-n', help='plugin name')
  opts.add_option('-c', help='classes directory')
  opts.add_option('-t', help='test report directory')
  opts.add_option('-o', help='output file', default='sonar-project.properties')
  args, _ = opts.parse_args()

  plugin_dir = path.abspath(__file__)
  for _ in range(0, 3):
    plugin_dir = path.dirname(plugin_dir)
  generate_project_properties(args.n, plugin_dir, path.abspath(args.c),
                              path.abspath(args.t), args.o)
