from sqlalchemy import Table, Column, Integer, String, Boolean, ForeignKey
from sqlalchemy.orm import relationship, backref
from .db import Base

services_dvrs = Table('services_dvrs',
    Base.metadata,
    Column('service_id', Integer(), ForeignKey('service.id')),
    Column('dvr_id', Integer(), ForeignKey('dvr.id')))


class Service(Base):
    __tablename__ = 'service'

    id = Column(Integer(), primary_key=True)
    name = Column(String(), nullable=False)
    client_id = Column(String(), nullable=False, unique=True)
    hostname = Column(String())
    html_path = Column(String())
    event_port = Column(Integer())
    active = Column(Boolean())

    def __init__(self, name, client_id, hostname, html_path, event_port, active):
        self.name = name
        self.client_id = client_id
        self.hostname = hostname
        self.html_path = html_path
        self.event_port = event_port
        self.active = active

    def __repr__(self):
        return "<Service name='{name}'>".format(name=self.name)


class DVR(Base):
    __tablename__ = 'dvr'

    id = Column(Integer(), primary_key=True)
    name = Column(String(), nullable=False)
    ip = Column(String(), nullable=False)
    user = Column(String(), nullable=False)
    password = Column(String(), nullable=False)

    services = relationship('Service', secondary=services_dvrs, backref=backref('dvrs', lazy='dynamic'))
    streams = relationship('Stream', backref=backref('dvr'), cascade="all, delete-orphan")
    ios = relationship('IO', backref=backref('dvr'), cascade="all, delete-orphan")

    def __init__(self, name, ip, user, password):
        self.name = name
        self.ip = ip
        self.user = user
        self.password = password

    def __repr__(self):
        return self.name


class Stream(Base):
    __tablename__ = 'stream'

    id = Column(Integer(), primary_key=True)
    name = Column(String())
    dvr_id = Column(Integer(), ForeignKey("dvr.id"), nullable=False)
    in_port = Column(Integer(), nullable=False)
    out_port = Column(Integer(), nullable=False)
    channels = Column(String())
    type = Column(Integer())

    def __init__(self, name, dvr_id, in_port, out_port, channels, type):
        self.name = name
        self.dvr_id = dvr_id
        self.in_port = in_port
        self.out_port = out_port
        self.channels = channels
        self.type = type

    def __repr__(self):
        return '<Stream {}>' % self.name


class IO(Base):
    __tablename__ = 'io'

    id = Column(Integer(), primary_key=True)
    name = Column(String(), nullable=False)
    dvr_id = Column(Integer(), ForeignKey("dvr.id"), nullable=False)
    port = Column(Integer(), nullable=False)
    state = Column(Integer(), nullable=False)
    enabled = Column(Boolean(), nullable=False)
    events_enabled = Column(Boolean(), nullable=False)

    doors = relationship('Door', backref=backref('io'), cascade="all, delete-orphan")

    def __init__(self, name, dvr_id, port, state, enabled, events_enabled):
        self.name = name
        self.dvr_id = dvr_id
        self.port = port
        self.state = state
        self.enabled = enabled
        self.events_enabled = events_enabled

    def __repr__(self):
        return '<IO {}>' % self.name


class Door(Base):
    __tablename__ = 'door'

    id = Column(Integer(), primary_key=True)
    name = Column(String())
    io_id = Column(Integer(), ForeignKey("io.id"), nullable=False)
    in_pin = Column(Integer(), nullable=False)
    out_pin = Column(Integer(), nullable=False)
    delay = Column(Integer(), nullable=False)
    nonc = Column(Integer(), nullable=False)

    def __init__(self, name, io_id, in_pin, out_pin, delay, nonc):
        self.name = name
        self.io_id = io_id
        self.in_pin = in_pin
        self.out_pin = out_pin
        self.delay = delay
        self.nonc = nonc

    def __repr__(self):
        return '<Door {}>' % self.name


roles_users = Table('roles_users',
    Base.metadata,
    Column('user_id', Integer(), ForeignKey('user.id')),
    Column('role_id', Integer(), ForeignKey('role.id')))


class Role(Base):
    __tablename__ = 'role'

    id = Column(Integer(), primary_key=True)
    name = Column(String(80), unique=True)
    description = Column(String(255))

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return '<Role %r>' % (self.name)


class User(Base):
    __tablename__ = 'user'

    id = Column(Integer(), primary_key=True)
    username = Column(String(255), unique=True)
    password = Column(String(255))
    active = Column(Boolean())
    roles = relationship('Role', secondary=roles_users, backref=backref('users', lazy='dynamic'))

    def __init__(self, username, password, active, roles):
        self.username = username
        self.password = password
        self.active = active
        self.roles = roles

    def __repr__(self):
        return '<User %r>' % (self.username)
