# -*- python -*-
# ex: set syntax=python:

# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# READ THIS:
# See http://dev.chromium.org/developers/testing/chromium-build-infrastructure

import os

# These modules come from scripts, which must be in the PYTHONPATH.
from master import master_utils
from master import slaves_list
from common import chromium_utils
from master.builders_pools import BuildersPools
from master.factory import annotator_factory
from master.try_job_http import TryJobHTTP

from buildbot.scheduler import Triggerable

import config
import master_site_config

ActiveMaster = master_site_config.NativeClientTryServer

nacl_source_url = (
    'https://chromium.googlesource.com/native_client/src/native_client')

MAIL_NOTIFIER = True

# This is the dictionary that the buildmaster pays attention to. We also use
# a shorter alias to save typing.
c = BuildmasterConfig = {}

config.DatabaseSetup(c)

####### CHANGESOURCES

c['change_source'] = [ ]

# Avoid merging requests.
c['mergeRequests'] = lambda *_: False


####### BUILDERS

c['builders'] = []

# FACTORIES

m_annotator = annotator_factory.AnnotatorFactory(ActiveMaster)

def F_NACL_RECIPE():
  return m_annotator.BaseFactory(recipe='nacl',
      factory_properties = {'slavetype': 'Trybot'})

def F_NACLPORTS_RECIPE():
  return m_annotator.BaseFactory(recipe='nacl_ports',
      factory_properties = {'slavetype': 'Trybot'})

def CreateBot(password=config.Master.GetBotPassword(),
              builder_name=None,
              project=None,
              slave_names=None,
              factory_properties=None):
  """Generates and returns a builder along with its slave(s).

  Implicitly create slave_name or slave_names if they weren't created or
  specified.
  If none of slave_name or slave_names is supplied, a slave name will be
  constructed from the builder name.
  """
  # Don't enable auto_reboot for people testing locally.
  auto_reboot = ActiveMaster.is_production_host
  # Arm board slaves have issue rebooting continuously.
  if 'arm_hw_' in builder_name:
    auto_reboot = False
  if project in ['nacl', 'nacl-toolchain']:
    builder_factory = F_NACL_RECIPE()
  else:
    assert False
  builddir = builder_name.replace(' ', '-')
  slavebuilddirs = {
      'nacl-toolchain-asan': 'nacl-asan',
      'nacl-toolchain-msan': 'nacl-msan',
      'nacl-toolchain-tsan': 'nacl-tsan',
      'nacl-toolchain-ubsan': 'nacl-ubsan',
  }
  if builder_name in slavebuilddirs:
    slavebuilddir = slavebuilddirs[builder_name]
  else:
    slavebuilddir = builddir
  builder = {
    'name': builder_name,
    'builddir': builddir,
    'slavebuilddir': slavebuilddir,
    'factory': builder_factory,
    'auto_reboot': auto_reboot,
  }
  if slave_names:
    builder['slavenames'] = slave_names
  else:
    builder['slavename'] = builder_name.replace(' ', '-')
  return builder


# Try queues.
pools = BuildersPools('nacl')


slaves_cfg = chromium_utils.ParsePythonCfg('slaves.cfg')
builder_categories = slaves_cfg['categories']
categories_to_slaves = slaves_cfg['categories_to_slaves']
categories_to_builders = slaves_cfg['categories_to_builders']


def GetSlaveNames(builder_name):
  return sum([categories_to_slaves[category]
      for category in builder_categories
      if builder_name in categories_to_builders[category]], [])

def GetAllBuilderNames():
  return list(set(sum(categories_to_builders.values(), [])))

all_builders = GetAllBuilderNames()
nacl_builders = [builder for builder in all_builders
    if builder.startswith('nacl-') and not builder.startswith('nacl-toolchain')]
nacl_toolchain_builders = [builder for builder in all_builders
    if builder.startswith('nacl-toolchain')]

projects = {
    'nacl': nacl_builders,
    'nacl-toolchain': nacl_toolchain_builders,
}

for project in projects:
  for builder_name in projects[project]:
    slave_names = GetSlaveNames(builder_name)
    builder = CreateBot(builder_name = builder_name, project = project,
                        slave_names = slave_names)
    c['builders'].append(builder)
    pools[project].append(builder_name)


b_nacl_presubmit = {
  'name': 'nacl-presubmit',
  'slavebuilddir': 'nacl',
  'factory':
      m_annotator.BaseFactory('run_presubmit', {'repo_name': 'nacl'}),
  'slavenames': categories_to_slaves['precise64']
}
c['builders'].append(b_nacl_presubmit)

# Set "root" build property to "native_client" in all nacl-* builders,
# set it to "src" on all others.
for b in c['builders']:
  if b['name'].startswith('nacl-'):
    b.setdefault('properties', {})['root'] = 'native_client'
  else:
    b.setdefault('properties', {})['root'] = 'src'

####### BUILDSLAVES

# The 'slaves' list defines the set of allowable buildslaves. List all the
# slaves registered to a builder. Remove dupes.
c['slaves'] = master_utils.AutoSetupSlaves(c['builders'],
                                           config.Master.GetBotPassword())


####### SCHEDULERS

# Configure the Schedulers;
# Main Tryscheduler for the try queue. groups is defined in the loop above.
c['schedulers'] = []

code_review_sites = {
  'nacl': ActiveMaster.code_review_site,
  'nacl-toolchain': ActiveMaster.code_review_site,
}
c['schedulers'].append(TryJobHTTP(
    name='try_job_http',
    port=ActiveMaster.try_job_port,
    code_review_sites=code_review_sites,
    pools=pools))

for mode in ['opt_panda', 'perf_panda']:
  s = Triggerable(
      name='arm_%s_hw_tests' % mode,
      builderNames=['nacl-arm_hw_%s' % mode])
  c['schedulers'].append(s)


####### STATUS TARGETS

# Buildbot master url:
# Must come before AutoSetupMaster().
c['buildbotURL'] = ActiveMaster.buildbot_url

# Adds common status and tools to this master.
master_utils.AutoSetupMaster(c, ActiveMaster, False,
                             public_html='../master.chromium/public_html',
                             templates=['../master.client.nacl/templates'])

# Add more.

if MAIL_NOTIFIER:
  # Add a dumb MailNotifier first so it will be used for BuildSlave with
  # notify_on_missing set when they go missing.
  from buildbot.status import mail
  c['status'].append(mail.MailNotifier(
      fromaddr=ActiveMaster.from_address,
      builders=[],
      relayhost=config.Master.smtp,
      lookup=master_utils.UsersAreEmails()))

  # Try job result emails.
  from master.try_mail_notifier import TryMailNotifier
  c['status'].append(TryMailNotifier(
      fromaddr=ActiveMaster.from_address,
      reply_to=ActiveMaster.reply_to,
      subject="try of %(reason)s @ r%(revision)s %(timestamp)s",
      mode='all',
      relayhost=config.Master.smtp,
      lookup=master_utils.UsersAreEmails()))


# Keep last try jobs, the default is too low. Must keep at least a few days
# worth of try jobs.
c['buildHorizon'] = 2000
c['logHorizon'] = 2000
# Must be at least 2x the number of slaves.
c['eventHorizon'] = 100
# Must be at least 2x the number of on-going builds.
c['buildCacheSize'] = 100


####### PROJECT IDENTITY

# The 'projectURL' string will be used to provide a link
# from buildbot HTML pages to your project's home page.
c['projectURL'] = 'http://go/ChromeTryServer'
