from pyramid.security import Allow, Everyone
from datetime import datetime

from sqlalchemy import (
    Column,
    Integer,
    Text,
    String,
    Float,
    DateTime,
    ForeignKey,
    )

from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy.orm import (
    scoped_session,
    sessionmaker,
    relationship
    )

from zope.sqlalchemy import ZopeTransactionExtension

DBSession = scoped_session(
    sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base()


# class Page(Base):
#     __tablename__ = 'wikipages'
#     uid = Column(Integer, primary_key=True)
#     title = Column(Text, unique=True)
#     body = Column(Text)

class Config(Base):
    __tablename__ = "configs"
    _id = Column(Integer, primary_key=True)
    parameter = Column(String(100), unique=True)
    val = Column(String(100), unique=True)
    created_on = Column(DateTime(), default=datetime.utcnow)
    updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)


class Device_type(Base):
    __tablename__ = "device_types"
    _id = Column(Integer, primary_key=True)
    device_type = Column(String(64))
    created_on = Column(DateTime(), default=datetime.utcnow)
    updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)


class Device(Base):
    __tablename__ = "devices"
    _id = Column(Integer, primary_key=True)
    device_type_id = Column(Integer, ForeignKey('device_types._id'))
    device_type = relationship(Device_type, primaryjoin=device_type_id == Device_type._id)
    address = Column(String(256))
    created_on = Column(DateTime(), default=datetime.utcnow)
    updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)


class Doc(Base):
    __tablename__ = "docs"
    _id = Column(Integer, primary_key=True)
    name = Column(String(256))
    created_on = Column(DateTime(), default=datetime.utcnow)
    updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)


class Tag(Base):
    __tablename__ = "tags"
    _id = Column(Integer, primary_key=True)
    name = Column(String(64))
    tag = Column(String(128))
    tag_category = Column(String(128))
    device_id = Column(Integer, ForeignKey('devices._id'))
    device = relationship(Device)
    description = Column(String(64))
    data_type = Column(String(64))
    change_threshold = Column(Float)
    guarantee_sec = Column(Integer)
    map_function = Column(String(64))
    units = Column(String(10))
    min_expected = Column(Float)
    max_expected = Column(Float)
    created_on = Column(DateTime(), default=datetime.utcnow)
    updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)


class Tag_val(Base):
    __tablename__ = "tag_vals"
    _id = Column(Integer, primary_key=True)
    tag_id = Column(Integer, ForeignKey('tags._id'))
    tag = relationship(Tag)
    value = Column(Float)
    created_on = Column(DateTime(), default=datetime.utcnow)
    updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)


class Card(Base):
    __tablename__ = "cards"
    _id = Column(Integer, primary_key=True)
    stroke_type = Column(String(32))
    stroke_number = Column(Integer)
    surf_pos = Column(Text)
    surf_lod = Column(Text)
    down_pos = Column(Text)
    down_lod = Column(Text)
    created_on = Column(DateTime(), default=datetime.utcnow)
    updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)


class GaugeOffVal(Base):
    __tablename__ = "gauge_off"
    _id = Column(Integer, primary_key=True)
    spm_average = Column(Float)
    downhole_gross_stroke_average = Column(Float)
    downhole_net_stroke_average = Column(Float)
    electricity_cost_total = Column(Float)
    fluid_level_average = Column(Float)
    full_card_production_total = Column(Float)
    inflow_rate_average = Column(Float)
    kWh_used_total = Column(Float)
    kWh_regen_total = Column(Float)
    lifting_cost_average = Column(Float)
    peak_pr_load = Column(Float)
    min_pr_load = Column(Float)
    percent_run = Column(Float)
    polished_rod_hp_average = Column(Float)
    pump_hp_average = Column(Float)
    production_total = Column(Float)
    pump_intake_pressure_average = Column(Float)
    surface_stroke_length_average = Column(Float)
    tubing_movement_average = Column(Float)
    created_on = Column(DateTime(), default=datetime.utcnow)
    updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)


class WellTest(Base):
    __tablename__ = "well_tests"
    _id = Column(Integer, primary_key=True)
    duration_hours = Column(Float)
    volume_h2o_actual = Column(Float)
    volume_oil_actual = Column(Float)
    volume_gas_actual = Column(Float)
    volume_h2o_projected = Column(Float)
    volume_oil_projected = Column(Float)
    volume_gas_projected = Column(Float)
    api_gravity_oil = Column(Float)
    spc_gravity_h2o = Column(Float)
    created_on = Column(DateTime(), default=datetime.utcnow)
    updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)


class Note(Base):
    __tablename__ = "notes"
    _id = Column(Integer, primary_key=True)
    note_text = Column(String(256))
    author = Column(String(128))
    created_on = Column(DateTime(), default=datetime.utcnow)
    updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)


class EventConfig(Base):
    __tablename__ = "event_configs"
    _id = Column(Integer, primary_key=True)
    name = Column(String(64))
    event_type = Column(String(64))
    tag = Column(String(128))
    condition = Column(String(64))
    device_id = Column(Integer, ForeignKey('devices._id'))
    device = relationship(Device)
    created_on = Column(DateTime(), default=datetime.utcnow)
    updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)


class Event(Base):
    __tablename__ = "events"
    _id = Column(Integer, primary_key=True)
    event_id = Column(Integer, ForeignKey('event_configs._id'))
    event = relationship(EventConfig)
    event_type = Column(String(64))
    event_condition = Column(String(64))
    created_on = Column(DateTime(), default=datetime.utcnow)
    updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)


class RunStatus(Base):
    __tablename__ = "run_status_log"
    _id = Column(Integer, primary_key=True)
    run_status = Column(String(64))
    created_on = Column(DateTime(), default=datetime.utcnow)
    updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)


class FluidShot(Base):
    __tablename__ = "fluid_shots"
    _id = Column(Integer, primary_key=True)
    pump_intake_pressure = Column(Float)
    created_on = Column(DateTime(), default=datetime.utcnow)
    updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)


class BackupRestore(Base):
    __tablename__ = "backup_restore"
    _id = Column(Integer, primary_key=True)
    tag = Column(String(128))
    tag_type = Column(String(128))
    device_id = Column(Integer, ForeignKey('devices._id'))
    device = relationship(Device)
    value = Column(String(128))
    created_on = Column(DateTime(), default=datetime.utcnow)
    updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)


class Root(object):
    __acl__ = [(Allow, Everyone, 'view'),
               (Allow, 'group:editors', 'edit')]

    def __init__(self, request):
        pass
