#!/usr/bin/python
# Copyright 2012 Google Inc. All Rights Reserved.
#
"""Base classes for configuration objects."""

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


import random


class QueryError(Exception):
  pass


class AttrSet(object):
  """A simple set of key-value pairs represented as a class with members."""

  __slots__ = ()

  def __init__(self, **kwargs):
    for key in self.__slots__:
      setattr(self, key, None)
    self.Set(**kwargs)

  def Set(self, **kwargs):
    for key, value in kwargs.iteritems():
      setattr(self, key, value)

  def Match(self, **kwargs):
    for key, value in kwargs.iteritems():
      ival = getattr(self, key)
      # None and False can match each other
      #gpylint: disable-msg=C6403
      if ival == False: ival = None
      if value == False: value = None
      if value == True and ival:
        continue  # any nonempty value is true, so match it
      if ival != value:
        return False
    return True

  def _Items(self):
    for key in self.__slots__:
      value = getattr(self, key)
      if value == True:  #gpylint: disable-msg=C6403
        yield key
      elif value is not None and value != False:  #gpylint: disable-msg=C6403
        yield '%s=%r' % (key, value)

  def __repr__(self):
    return '<%s>' % ','.join(self._Items())

  def __str__(self):
    return '\n  '.join(['%s:' % self.__class__.__name__]
                       + list(self._Items()))


class Host(AttrSet):
  __slots__ = (
      'name',
      'ether',
      'ip',
      'ip6',
      'cpu',
      'platform',
      'serialport',
      'serialno',
      'is_canary',
      'is_alive',
      'is_alive_net',
      'is_storage',
      'is_tv',
      'is_nfsroot',
      'has_ether',
      'has_moca',
      'has_wifi',
  )


class Hosts(list):
  """A searchable/queryable list of Host objects."""

  def FindAll(self, **kwargs):
    return [i for i in self if i.Match(**kwargs)]

  def _FindOne(self, **kwargs):
    l = self.FindAll(**kwargs)
    if l:
      return l[0]

  def FindOne(self, **kwargs):
    v = self._FindOne(**kwargs)
    if v is None:
      raise KeyError(kwargs)
    return v

  def FindOrAdd(self, **kwargs):
    h = self._FindOne(**kwargs)
    if not h:
      h = Host(**kwargs)
      self.append(h)
    if not h.name:
      h.name = h.ether or h.serialno or h.ip or h.ip6
    return h

  def Query(self, mincount=None, maxcount=None, randomize=False, **kwargs):
    """Query the hosts list according to the given parameters.

    Args:
      mincount: the minimum number of hosts to return.
      maxcount: the maximum number of hosts to return.
      randomize: return a random subset or the first maxcount matches.
      **kwargs: key=value pairs to pass to hosts.FindAll().
    Returns:
      A list of matching Host objects.
    Raises:
      QueryError: if mincount > maxcount or other invalid options.
    """
    matches = self.FindAll(**kwargs)
    if maxcount and maxcount < 0:
      raise QueryError('max(%s) must be >= 0' % maxcount)
    if maxcount and mincount > maxcount:
      raise QueryError('min(%s) > max(%s)' % (mincount, maxcount))
    if mincount > len(matches):
      raise QueryError('not enough matches found (got=%d, wanted=%r)'
                       % (len(matches), mincount))
    if randomize:
      random.shuffle(matches)
    else:
      matches.sort(key=lambda i: (i.name, i.serialno, i.ether, i.ip6, i.ip))
    if maxcount is not None and len(matches) > maxcount:
      matches = matches[:maxcount]
    return matches

  def __str__(self):
    return '\n'.join(str(i) for i in self)


hosts = Hosts()


def main():
  print 'hello'
  hosts.FindOrAdd(ether='11:22:33:44:55:66').Set(name='myhost',
                                                 ip='1.2.3.4')
  print hosts


if __name__ == '__main__':
  main()
