#!/usr/bin/env python

# This script prepares this ONOS directory so that the Sonar Scanner can be run.
#  - Build ONOS
#  - Run tests on a per module basis, stage surefire-reports and jacoco.exec
#  - Generate sonar-project.properties file

import json
import os

from shutil import copy, copytree, rmtree
from subprocess import call, check_call, check_output

# FIXME pull the version from the Buck version file
ONOS_VERSION='1.11.0-rc3'

# SonarQube property file name and template
FILE_NAME = 'sonar-project.properties'
ROOT_TEMPLATE = '''# Auto-generated properties file
sonar.projectKey=%(key)s
sonar.projectName=%(name)s
sonar.projectVersion=%(version)s

#sonar.sources=src
sonar.sourceEncoding=UTF-8
sonar.java.target = 1.8
sonar.java.source = 1.8
sonar.language=java

sonar.junit.reportsPath = surefire-reports
# global jacoco
#sonar.jacoco.reportPath = %(jacoco)s
# local jacoco
sonar.jacoco.reportPath = jacoco.exec

sonar.modules=%(modules)s

'''

BUCK = 'onos-buck'

# Change to $ONOS_ROOT
ONOS_ROOT = os.environ[ 'ONOS_ROOT' ]
if ONOS_ROOT:
  os.chdir( ONOS_ROOT )

def splitTarget(target):
  path, module = target.split(':', 2)
  path = path.replace('//', '', 1)
  return path, module

def runCmd(cmd):
  output = check_output( cmd ).rstrip()
  return output.split('\n') if output else []

# TODO do we need to start with a clean slate?
#runCmd([BUCK, 'clean'])

# Find all onos_jar rules
targets = runCmd([BUCK, 'query', "kind('onos_jar', '//...')"])
#targets = ['//core/net:onos-core-net']
print targets
non_osgi_targets = ['%s#non-osgi' % t for t in targets]

# Build all targets to fill buck-out/bin
print runCmd([BUCK, 'build', '--no-cache'] + targets + non_osgi_targets)

# Find all tests associated with onos_jar rules
#FIXME we may want to insert kind('java_test', testsof...)
output = runCmd([BUCK, 'query', '--json', "testsof('%s')"] + targets)
test_map = json.loads(output[0])

# Flatten the values in the test target map
test_targets = [t for ts in test_map.values() for t in ts]
print test_targets

# Build run tests
#print runCmd([BUCK, 'test', '--no-cache', '--code-coverage', '--no-results-cache'] + test_targets)

# Build the sonar rules for each target
sonar_files = runCmd([BUCK, 'build', '--show-output'] + ['%s-sonar' % t for t in (targets + test_targets)])
sonar_files = dict([i.split(' ') for i in sonar_files[1:]]) # drop the first line; it's boilerplate
print sonar_files


def write_module(target, out):
  path, module_name = splitTarget(target)
  out.write('%s.sonar.projectBaseDir=%s\n' % ( module_name, path ))
  out.write('%(name)s.sonar.projectName=%(name)s\n' % {'name': module_name})

  tests = test_map[target] if target in test_map else []

  module_targets = [target] + tests
  for property in [sonar_files[t+'-sonar'] for t in module_targets]:
    print property
    with open(property, 'r') as f:
      for line in f.readlines():
        out.write('%s.%s' % (module_name, line))

  if tests:
    rmtree(path + '/surefire-reports', ignore_errors=True)
    rmtree('surefire-reports', ignore_errors=True)
    runCmd([BUCK, 'test',
            '--no-cache', '--no-results-cache',
            '--code-coverage',
            '--no-results-cache',
            '--surefire-xml', 'surefire-reports'
            ] + tests)
    copy('buck-out/gen/jacoco/jacoco.exec', path)
    #write jacoco.exec path to out; not needed.. this is the default
    copytree('surefire-reports', path + '/surefire-reports')
    rmtree('surefire-reports')

# Write the sonar properties file
with open(FILE_NAME, 'w') as out:
  out.write(ROOT_TEMPLATE % {
    'name': 'onos',
    'key': 'org.onosproject:onos',
    'version': ONOS_VERSION,
    'jacoco': '%s/buck-out/gen/jacoco/jacoco.exec' % ONOS_ROOT,
    'modules': ','.join([splitTarget(t)[1] for t in targets])
  })
  for target in targets:
    print target
    write_module(target, out)
