from . import db,login_manger
from werkzeug.security import generate_password_hash,check_password_hash
from flask_login import UserMixin,AnonymousUserMixin
from itsdangerous import TimedJSONWebSignatureSerializer
from flask import current_app
from datetime import datetime
class Role(db.Model):
    __tablename__ = 'roles'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    default = db.Column(db.Boolean,default=False,index=True)
    permission = db.Column(db.Integer)
    users = db.relationship('User', backref='role', lazy='dynamic')

    @staticmethod
    def insert_roles():
        roles = {
            'Student':(Permission.COMMENT,True),
            'Teacher':(Permission.COMMENT | Permission.ADD_COURSES,False),
            'Administrator':(0xff,False)
        }
        for r in roles:
            role = Role.query.filter_by(name=r).first()
            if role is None:
                role = Role(name=r)
            role.permission = roles[r][0]
            role.default = roles[r][1]
            db.session.add(role)
        db.session.commit()

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

class Permission:
    COMMENT = 0x01
    ADD_COURSES = 0x02
    DELETE_COMMENT = 0x04
    ADMIN = 0x80

class Colleage(db.Model):
    __tablename__ = 'colleages'
    id = db.Column(db.Integer,primary_key=True)
    name = db.Cloumn(db.String(64),unique=True)
    major = db.relationship('Major',backref='colleage',lazy='dynamic')
    user = db.releationship('User',backref='colleage',lazy='dymanic')
    course = db.releationship('Course',backref='colleage',lazy='dymanic')
    about_me = db.Column(db.Text())
    @staticmethod
    def insert_colleages():
        colleages = {'计算机与信息学院':'我们是计算机学院','数理学院':'我们是数理学院'}
        for n in colleages:
            colleage = Colleage.query.filter_by(name=n)
            if colleage is None:
                colleage = Colleage(name=n)
            colleage.about_me = colleage[n]
            db.session.add(colleage)
        db.session.commit()


class Major(db.Model):
    __table__ = 'Majors'
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(64),unique=True)
    colleage_id = db.Column(db.Integer,db.ForeignKey('colleages.id'))
    about_me = db.Column(db.Text())
    @staticmethod
    def insert_majors():
        major_one = Major(name = '软件工程',colleage = '计算机与信息学院',about_me = '对，软件工程')
        major_two = Major(name = '应用数学',colleage = '数理学院',about_me = '对．应用数学')
        db.session.add(major_one,major_two)
        db.session.commit()

class Course(db.Model):
    __table__ = 'courses'
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(64),unique=True)
    colleage = db.Column(db.Integer,db.ForeignKey('colleages.id'))


class User(UserMixin,db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(64),unique=True,index=True)
    username = db.Column(db.String(64), unique=True, index=True)
    nick = db.Column(db.String(64))
    major = db.Column(db.String(64))
    colleage = db.Column(db.String(64))
    about_me = db.Column(db.Text())
    member_since = db.Column(db.DateTime(),default=datetime.now())
    last_seen = db.Column(db.DateTime(),default=datetime.now())
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
    password_hash = db.Column(db.String(128))
    active = db.Column(db.Boolean,default = False)

    @property
    def password(self):
        raise AttributeError('password is not a readable attribute')

    @password.setter
    def password(self,password):
        self.password_hash = generate_password_hash(password)
    def verify_password(self,password):
        return check_password_hash(self.password_hash,password)

    @login_manger.user_loader
    def load_user(user_id):
        return User.query.get(int(user_id))

    def generate_confirmation_token(self,expiration = 3600):
        s = TimedJSONWebSignatureSerializer(current_app.config['SECRET_KEY'],expiration)
        return s.dumps({'confirm':self.id})

    def confirm(self,token):
        s = TimedJSONWebSignatureSerializer(current_app.config['SECRET_KEY'])
        try:
            data = s.load(token)
        except:
            return False
        if data.get('confirm') != self.id:
            return False
        self.active = True
        db.session.add(self)
        return True

    def __repr__(self):
        return '<User %r>' % self.username
    def __init__(self,**kwargs):
        super(User,self).__init__(**kwargs)
        if self.role is None:
            if self.email == current_app.config['AHPUCOURSES_ADMIN']:
                self.role = Role.query.filter_by(permission=0xff).first()
            if self.email is None:
                self.role = Role.query.filter_by(default=True).first()

    def can(self, permission):
        return self.role is not None and \
            (self.role.permission & permission) == permission

    def is_administrator(self):
        return self.can(Permission.ADMIN)

    def update_last_seen(self):
        self.last_seen = datetime.now()
        db.session.add(self)


class AnonymousUser(AnonymousUserMixin):
    def can(self,permission):
        return False

    def is_administrator(self):
        return False




