#!/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.9.2-SNAPSHOT'

# 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)
