#!/usr/bin/env python
# Copyright (c) 2018 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.

import argparse
import difflib
import os
import string
import sys


# Path to the root of the current chromium checkout.
CHROMIUM_DIR = os.path.abspath(os.path.join(
    os.path.dirname(__file__), '..', '..', '..'))


MD_HEADER = """# List of CQ builders

This page is auto generated using the script
//infra/config/branch/cq_config_presubmit.py. Do not manually edit.

[TOC]

Each builder name links to that builder on Milo. The "Backing builders" links
point to the file used to determine which configurations a builder should copy
when running. These links might 404 or error; they are hard-coded right now,
using common assumptions about how builders are configured.
"""


REQUIRED_HEADER = """
These builders must pass before a CL may land."""


OPTIONAL_HEADER = """These builders optionally run, depending on the files in a
CL. For example, a CL which touches `//gpu/BUILD.gn` would trigger the builder
`android_optional_gpu_tests_rel`, due to the `path_regexp` values for that
builder."""


EXPERIMENTAL_HEADER = """
These builders are run on some percentage of builds. Their results are ignored
by CQ. These are often used to test new configurations before they are added
as required builders."""


BUILDER_VIEW_URL = (
    'https://ci.chromium.org/p/chromium/builders/luci.chromium.try/')


CODE_SEARCH_BASE = 'https://cs.chromium.org/'


TRYBOT_SOURCE_URL = CODE_SEARCH_BASE + 'search/?q=file:trybots.py+'


CQ_CONFIG_LOCATION_URL = (
    CODE_SEARCH_BASE + 'search/?q=package:%5Echromium$+file:cq.cfg+')


REGEX_SEARCH_URL = CODE_SEARCH_BASE + 'search/?q=package:%5Echromium$+'


def parse_text_proto_message(lines):
  """Parses a text proto. LOW QUALITY, MAY EASILY BREAK.

  If you really need to parse text protos, use the actual python library for
  protobufs. This exists because the .proto file for cq.cfg lives in another
  repository.
  """
  data = {}

  linenum = 0
  # Tracks the current comment. Gets cleared if there's a blank line. Is added
  # to submessages, to allow for builders to contain comments.
  current_comment = None
  while linenum < len(lines):
    line = lines[linenum].strip()
    if not line:
      current_comment = None
      linenum += 1
    elif line.startswith('#'):
      if current_comment:
        current_comment += '\n' + line[1:]
      else:
        current_comment = line[1:]
      linenum += 1
    elif '{' in line:
      # Sub message. Put before the ':' clause so that it correctly handles one
      # line messages.
      end = linenum
      count = 0
      newlines = []
      while end < len(lines):
        inner_line = lines[end]
        if '{' in inner_line:
          count += 1
        if '}' in inner_line:
          count -= 1

        if end == linenum:
          newline = inner_line.split('{', 1)[1]
          if count == 0:
            newline = newline.split('}')[0]
          newlines.append(newline)
        elif count == 0:
          newlines.append(inner_line.split('}')[0])
        else:
          newlines.append(inner_line)
        end += 1
        if count == 0:
          break
      name = line.split('{')[0].strip()
      value = parse_text_proto_message(newlines)
      if current_comment:
        value['comment'] = current_comment
        current_comment = None

      if name in data:
        data[name].append(value)
      else:
        data[name] = [value]
      linenum = end
    elif ':' in line:
      # It's a field
      name, value = line.split(':', 1)
      value = value.strip()
      if value.startswith('"'):
        value = value.strip('"')

      if name in data:
        data[name].append(value)
      else:
        data[name] = [value]
      linenum += 1
    else:
      raise ValueError('Invalid line (number %d):\n%s' % (linenum, line))

  return data


class BuilderList(object):
  def __init__(self, builders):
    self.builders = builders

  def sort(self):
    """Sorts the builder list.

    Sorts the builders in place. Orders them into three groups: experimental,
    required, and optional."""
    self.builders.sort(key=lambda b: '%s|%s|%s' % (
        'z' if b.get('experiment_percentage') else 'a',
        'z' if b.get('path_regexp') else 'a',
        b['name']))

  def by_section(self):
    required = []
    experimental = []
    optional = []
    for b in self.builders:
      # Don't handle if something is both optional and experimental
      if b.get('path_regexp'):
        optional.append(b)
      elif b.get('experiment_percentage'):
        experimental.append(b)
      else:
        required.append(b)

    return required, optional, experimental


class CQConfig(object):
  def __init__(self, lines):
    self._value = parse_text_proto_message(lines)

  @staticmethod
  def from_file(path):
    with open(path) as f:
      lines = f.readlines()

    return CQConfig(lines)

  @property
  def version(self):
    return int(self._value['version'][0])

  def builder_list(self, pred=None):
    """Returns a list of builders.

    pred is a predicate used to decide if a builder should be returned. It takes
    the bucket and builder as arguments."""
    items = []
    for bucket in (
        self._value['verifiers'][0]['try_job'][0]['buckets']):
      for b in bucket['builders']:
        if pred and not pred(bucket, b):
          continue
        items.append(b)
    return BuilderList(items)

  def get_markdown_doc(self):
    lines = []
    for l in MD_HEADER.split('\n'):
      lines.append(l)

    bl = self.builder_list()
    req, opt, exp = bl.by_section()
    for title, header, builders in (
        ('Required builders', REQUIRED_HEADER, req),
        ('Optional builders', OPTIONAL_HEADER, opt),
        ('Experimental builders', EXPERIMENTAL_HEADER, exp),
    ):
      lines.append('## %s' % title)
      lines.append('')
      for l in header.strip().split('\n'):
        lines.append(l)
      lines.append('')
      for b in builders:
        lines.append(
            '* [%s](%s) ([`cq.cfg` entry](%s)) ([matching builders](%s))' % (
            b['name'][0], BUILDER_VIEW_URL + b['name'][0],
            CQ_CONFIG_LOCATION_URL + b['name'][0],
            TRYBOT_SOURCE_URL + b['name'][0],))
        lines.append('')
        if 'comment' in b:
          for l in b['comment'].split('\n'):
            lines.append('  ' + l.strip())
          lines.append('')
        if 'path_regexp' in b:
          lines.append('  Path regular expressions:')
          for regex in b['path_regexp']:
            regex_title = '//' + regex.lstrip('/')
            url = None
            if regex.endswith('.+'):
              regex = regex[:-len('.+')]
              if all(
                  # Equals sign and dashes used by layout tests.
                  c in string.ascii_letters + string.digits + '/-_='
                  for c in regex):
                # Assume the regex is targeting a single path, direct link to
                # it. Check to make sure we don't have weird characters, like
                # ()|, which could mean it's a regex.
                url = CODE_SEARCH_BASE + 'chromium/src/' + regex
            lines.append('    * [`%s`](%s)' % (
                regex_title, url or REGEX_SEARCH_URL + 'file:' + regex))
          lines.append('')
        if 'experiment_percentage' in b:
          lines.append('  * Experimental percentage: %s' % (
              b['experiment_percentage'][0]))
          lines.append('')
      lines.append('')

    return '\n'.join(lines)


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument(
    '-c', '--check', action='store_true', help=
    'Do consistency checks of cq.cfg and generated files. Used during'
    'presubmit. Causes the tool to not generate any files.')
  args = parser.parse_args()

  exit_code = 0

  cfg = CQConfig.from_file(os.path.join(
      CHROMIUM_DIR, 'infra', 'config', 'branch', 'cq.cfg'))
  if cfg.version != 1:
    raise ValueError("Expected version 1, got %r" % cfg.version)

  # Only force sorting on luci.chromium.try builders. Others should go away soon
  # anyways...
  bl = cfg.builder_list(lambda bucket, builder: bucket == 'luci.chromium.try')
  names = [b['name'][0] for b in bl.builders]
  bl.sort() # Changes the bl, so the next line is sorted.
  sorted_names = [b['name'][0] for b in bl.builders]
  if sorted_names != names:
    print 'ERROR: cq.cfg is unsorted.',
    if args.check:
      print
    else:
      print ' Please sort as follows:'
      for line in difflib.unified_diff(
          names,
          sorted_names, fromfile='current', tofile='sorted'):
        print line
    exit_code = 1

  if args.check:
    # TODO(martiniss): Add a check for path_regexp, to make sure they're valid
    # paths.
    with open(os.path.join(
        CHROMIUM_DIR, 'docs', 'infra', 'cq_builders.md')) as f:
      if cfg.get_markdown_doc() != f.read():
        print (
            'Markdown file is out of date. Please run '
            '`//infra/config/branch/cq_cfg_presubmit.py to regenerate the '
            'docs.')
        exit_code = 1
  else:
    with open(os.path.join(
        CHROMIUM_DIR, 'docs', 'infra', 'cq_builders.md'), 'w') as f:
      f.write(cfg.get_markdown_doc())

  return exit_code


if __name__ == '__main__':
  sys.exit(main())
