import collections


def _build_prefix(params):
  """Constructs a LogDog stream prefix and tags from the supplied properties.

  The returned prefix is of the form:
  bb/<mastername>/<buildername>/<buildnumber>

  Any path-incompatible characters will be flattened to underscores.

  Returns (prefix, tags):
    prefix (str): the LogDog stream prefix.
    tags (dict): A dict of LogDog tags to add.
  """
  def normalize(s):
    parts = []
    for ch in str(s):
      if ch.isalnum() or ch in ':_-.':
        parts.append(ch)
      else:
        parts.append('_')
    if not parts[0].isalnum():
      parts.insert(0, 's_')
    return ''.join(parts)

  mastername, buildername, buildnumber = (normalize(p) for p in (
      params.mastername, params.buildername, params.buildnumber))

  parts = ['bb', mastername, buildername]
  if params.generation:
    parts += [params.generation]
  parts += [buildnumber]
  prefix = '/'.join(str(x) for x in parts)

  viewer_url = (
      'https://luci-milo.appspot.com/buildbot/%(mastername)s/%(buildername)s/'
      '%(buildnumber)d' % params._asdict())
  tags = collections.OrderedDict((
      ('buildbot.master', mastername),
      ('buildbot.builder', buildername),
      ('buildbot.buildnumber', str(buildnumber)),
      ('logdog.viewer_url', viewer_url),
  ))
  return prefix, tags