#!/usr/bin/env python
# Copyright 2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Runs selected gRPC test/build tasks."""

from __future__ import print_function

import argparse
import multiprocessing
import sys

import artifacts.artifact_targets as artifact_targets
import artifacts.distribtest_targets as distribtest_targets
import artifacts.package_targets as package_targets
import python_utils.jobset as jobset
import python_utils.report_utils as report_utils

_TARGETS = []
_TARGETS += artifact_targets.targets()
_TARGETS += distribtest_targets.targets()
_TARGETS += package_targets.targets()

def _create_build_map():
  """Maps task names and labels to list of tasks to be built."""
  target_build_map = dict([(target.name, [target])
                           for target in _TARGETS])
  if len(_TARGETS) > len(target_build_map.keys()):
    raise Exception('Target names need to be unique')

  label_build_map = {}
  label_build_map['all'] = [t for t in _TARGETS]  # to build all targets
  for target in _TARGETS:
    for label in target.labels:
      if label in label_build_map:
        label_build_map[label].append(target)
      else:
        label_build_map[label] = [target]

  if set(target_build_map.keys()).intersection(label_build_map.keys()):
    raise Exception('Target names need to be distinct from label names')
  return dict( target_build_map.items() + label_build_map.items())


_BUILD_MAP = _create_build_map()

argp = argparse.ArgumentParser(description='Runs build/test targets.')
argp.add_argument('-b', '--build',
                  choices=sorted(_BUILD_MAP.keys()),
                  nargs='+',
                  default=['all'],
                  help='Target name or target label to build.')
argp.add_argument('-f', '--filter',
                  choices=sorted(_BUILD_MAP.keys()),
                  nargs='+',
                  default=[],
                  help='Filter targets to build with AND semantics.')
argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int)
argp.add_argument('-t', '--travis',
                  default=False,
                  action='store_const',
                  const=True)

args = argp.parse_args()

# Figure out which targets to build
targets = []
for label in args.build:
  targets += _BUILD_MAP[label]

# Among targets selected by -b, filter out those that don't match the filter
targets = [t for t in targets if all(f in t.labels for f in args.filter)]
targets = sorted(set(targets))

# Execute pre-build phase
prebuild_jobs = []
for target in targets:
  prebuild_jobs += target.pre_build_jobspecs()
if prebuild_jobs:
  num_failures, _ = jobset.run(
    prebuild_jobs, newline_on_success=True, maxjobs=args.jobs)
  if num_failures != 0:
    jobset.message('FAILED', 'Pre-build phase failed.', do_newline=True)
    sys.exit(1)

build_jobs = []
for target in targets:
  build_jobs.append(target.build_jobspec())
if not build_jobs:
  print('Nothing to build.')
  sys.exit(1)

jobset.message('START', 'Building targets.', do_newline=True)
num_failures, resultset = jobset.run(
    build_jobs, newline_on_success=True, maxjobs=args.jobs)
report_utils.render_junit_xml_report(resultset, 'report_taskrunner_sponge_log.xml',
                                     suite_name='tasks')
if num_failures == 0:
  jobset.message('SUCCESS', 'All targets built successfully.',
                 do_newline=True)
else:
  jobset.message('FAILED', 'Failed to build targets.',
                 do_newline=True)
  sys.exit(1)
