#coding:utf-8
from sqlalchemy import *
import sqlalchemy.orm
import sqlalchemy.ext.declarative

Base = sqlalchemy.ext.declarative.declarative_base()
 
class SunhpcBase(object):
    """Additional base class of Sunhpc ORM hierarchy which includes some
    helper methods for all classes"""

    @property
    def session(self):
        """Singelton which return the session of the object"""
        return sqlalchemy.orm.session.object_session(self)


    def delete(self):
        """instance method to autodelete the instance which calls it

        so you can use
        node.delete()"""
        self.session.delete(self)

    @classmethod
    def loadOne(cls, session, **kwargs):
        """ """
        return cls.load(session, **kwargs).one()

    @classmethod
    def load(cls, session, **kwargs):
        """
        this method allow us to run query on all the mapping objects
        simply using 

        e.g.::

          node = Nodes.load(session, Name='compute-0-0', Cpus=2)
          nic = Network.load(session, Name='compute-0-0', Interface='eth0')

        taken from:
        http://petrushev.wordpress.com/2010/06/22/sqlalchemy-base-model/
        """
        q = session.query(cls)
        filters = [getattr(cls, field_name)==kwargs[field_name] \
                for field_name in kwargs]
        return q.filter(and_(*filters))

class Attribute(SunhpcBase, Base):
    __tablename__   = 'attributes'
    __table_args__  = {}
    ID          = Column('ID', Integer, primary_key=True, nullable=False, autoincrement=True)
    attr        = Column('Attr', String(128), nullable=False)
    value       = Column('Value', TEXT())
    shadow      = Column('Shadow', TEXT())
    categoryID  = Column('Category', Integer, ForeignKey('categories.ID'), nullable=False)
    catindexID  = Column('Catindex', Integer, ForeignKey('catindex.ID'), nullable=False)

class Bootaction(SunhpcBase, Base):
    __tablename__   = 'bootactions'
    __table_args__  = {}

    ID      = Column('ID', Integer, primary_key=True, nullable=False, autoincrement=True)
    action  = Column('Action', String(256))
    kernel  = Column('Kernel', String(256))
    ramdisk = Column('Ramdisk', String(256))
    args    = Column('Args', String(1024))

class Category(SunhpcBase, Base):
    __tablename__   = 'categories'
    __table_args__  = {}
    ID          = Column('ID', Integer, primary_key=True, nullable=False, autoincrement=True)
    name        = Column('Name', String(64), nullable=False)
    description = Column('Description', String(512))
    attributes  = sqlalchemy.orm.relationship('Attribute', backref='category')
    catindexes  = sqlalchemy.orm.relationship('Catindex', backref='category')

class Catindex(SunhpcBase, Base):
    __tablename__   = 'catindex'
    __table_args__  = {}
    ID          = Column('ID', Integer, primary_key=True, nullable=False, autoincrement=True)
    name        = Column('Name', String(64), nullable=False)
    categoryID  = Column('Category', Integer, ForeignKey('categories.ID'), nullable=False)
    attributes  = sqlalchemy.orm.relationship('Attribute', backref='catindex')

class Node(SunhpcBase, Base):
    __tablename__   = 'nodes'
    __table_args__  = {}

    ID              = Column('ID', Integer, primary_key=True, nullable=False, autoincrement=True)
    name            = Column('Name', String(128))
    cpus            = Column('CPUs', Integer, nullable=False, default=1)
    rack            = Column('Rack', Integer)
    rank            = Column('Rank', Integer)
    arch            = Column('Arch', String(32))
    os              = Column('OS', Enum(u'linux', u'sunos'), nullable=False, default=u'linux')
    alias           = Column('Alias', String(128), default='')
    status          = Column('Status', String(128), default='install')

    networks_ID = sqlalchemy.orm.relationship("Network", backref="nodes")
    pub_keys_ID = sqlalchemy.orm.relationship("PublicKey", backref="nodes")
    def __repr__(self):
        return "<Node(name='%s')>" % (self.name)

class Network(SunhpcBase, Base):
    __tablename__   = 'networks'
    __table_args__  = {}
    ID          = Column('ID', Integer, primary_key=True, nullable=False, autoincrement=True)
    node        = Column('Node', Integer, ForeignKey('nodes.ID'))
    mac         = Column('MAC', String(64))
    ip          = Column('IP', String(32))
    name        = Column('Name', String(128))
    device      = Column('Device', String(32))
    subnet_ID   = Column('Subnet', Integer, ForeignKey('subnets.ID'))

class Subnet(SunhpcBase, Base):
    __tablename__  = 'subnets'
    __table_args__ = {}
    ID          = Column('ID', Integer, primary_key=True, nullable=False, autoincrement=True)
    name        = Column('name', String(32), nullable=False, unique=True)
    dnszone     = Column('dnszone', String(64), nullable=False, unique=True)
    subnet      = Column('subnet', String(32), nullable=False)
    netmask     = Column('netmask', String(32), nullable=False)
    mtu         = Column('mtu', Integer, default=1500)
    servedns    = Column('servedns', Boolean, default=False)
    networks    = sqlalchemy.orm.relationship('Network', backref='subnet')

class PublicKey(SunhpcBase, Base):
    __tablename__   = 'publickeys'
    __table_args__  = {}

    ID          = Column('ID', Integer, primary_key=True, nullable=False, autoincrement=True)
    node        = Column('Node', Integer, ForeignKey('nodes.ID'), nullable=False)
    public_key  = Column('Public_Key', String(4096))
    description = Column('Description', String(4096))

class Roll(SunhpcBase, Base):
    __tablename__   = 'rolls'
    __table_args__  = {}

    ID      = Column('ID', Integer, primary_key=True, nullable=False, autoincrement=True)
    name    = Column('Name', String(128), nullable=False)
    version = Column('Version', String(32), nullable=False)
    arch    = Column('Arch', String(32), nullable=False)
    os      = Column('OS', Enum('linux', 'sunos'), nullable=False, default=u'linux')
    enabled = Column('Enabled', Enum(u'yes', u'no'), nullable=False, default=u'yes')

class SecNode(SunhpcBase, Base):
    __tablename__   = 'secnodes'
    __table_args__  = {}
    attr    = Column('Attr', String(128), primary_key=True, nullable=False)
    enc     = Column('Enc', String(64))
    node    = Column('Node', Integer, primary_key=True, nullable=False)
    value   = Column('Value', TEXT())

class SecGlobal(SunhpcBase, Base):
    __tablename__   = 'secglobals'
    __table_args__  = {}
    attr    = Column('Attr', String(128), primary_key=True, nullable=False)
    enc     = Column('Enc', String(64))
    value   = Column('Value', TEXT())

class Partition(SunhpcBase, Base):
    __tablename__   = 'partitions'
    __table_args__  = {}
    device          = Column('Device', String(128), nullable=False)
    formatFlags     = Column('FormatFlags', String(128), nullable=False)
    fsType          = Column('FsType', String(128), nullable=False)
    ID              = Column('ID', Integer, primary_key=True, nullable=False, autoincrement=True)
    mountpoint      = Column('Mountpoint', String(128), nullable=False)
    node            = Column('Node', Integer, nullable=False)
    partitionFlags  = Column('PartitionFlags', String(128), nullable=False)
    partitionID     = Column('PartitionID', String(128), nullable=False)
    partitionSize   = Column('PartitionSize', String(128), nullable=False)
    sectorStart     = Column('SectorStart', String(128), nullable=False)


