#!/usr/bin/python
# Copyright 2012 Google Inc. All Rights Reserved.
#
"""Test configurations.  Includes a list of auto-probed bruno devices."""

import re
import sys
from configs import hosts
from configs.core import Host
from configs.core import QueryError
from portsh import options

__author__ = 'Avery Pennarun (apenwarr@google.com)'


optspec = """
config [options...] <bool|^bool|key=value>...
--
random     Choose random matches instead of the first ones
max=       Return no more than max= matches
min=       If less than min= matches, return an error code
n,num=     Return exactly num= matches
v,verbose  Display the entire config entry for each match, not just the name
k,keys=    If -v isn't given, show these comma/space-separated attrs [name]
"""


def main():
  o = options.Options(optspec)
  opt, _, extra = o.parse(sys.argv[1:])
  if opt.num:
    if opt.min or opt.max:
      o.fatal("don't specify --num with --min/--max")
    opt.min = opt.max = opt.num

  kwargs = dict(is_alive=True)
  for kvs in extra:
    kv = kvs.split('=', 1) + [None]
    key = kv[0]
    value = kv[1]
    if not hasattr(Host, key):
      o.fatal('no key named %r; valid keys: %s'
              % (key, ', '.join(Host.__slots__)))
      sys.exit(1)
    if key.startswith('^'):
      kwargs[key[1:]] = False
    elif value is not None:
      kwargs[key] = value
    else:
      kwargs[key] = True
  try:
    matches = hosts.Query(mincount=opt.min, maxcount=opt.max,
                          randomize=opt.random, **kwargs)
  except QueryError, e:
    o.fatal(str(e))
  if opt.verbose:
    for match in matches:
      print match
  else:
    keys = re.split(r'[,\s]', opt.keys)
    for key in keys:
      if not hasattr(Host, key):
        o.fatal('no key named %r; valid keys: %s'
                % (key, ', '.join(Host.__slots__)))
    for match in matches:
      print ','.join(str(getattr(match, key) or '') for key in keys)


if __name__ == '__main__':
  main()
