#!/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.10.5-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)
