#!/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

# 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
# FIXME pull the version from the Buck version file
with open(FILE_NAME, 'w') as out:
  out.write(ROOT_TEMPLATE % {
    'name': 'onos',
    'key': 'org.onosproject:onos',
    'version': '1.8.0-SNAPSHOT',
    '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)
