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

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


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 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',
  )


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 FindOrAdd(self, **kwargs):
    h = self.FindOne(**kwargs)
    if not h:
      h = Host(**kwargs)
      self.append(h)
    return h

  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()
