from models.user import User as users
from models.post import Post as post
import secrets
import hashlib
from datetime import datetime, timedelta
from sqlalchemy.orm import Session
from models.logs import Log
from models.syscost import PerformanceData
class Fpost:
    def __init__(self,session:Session):
        self.session=session
        return
    

    def getlist(self):
        results = self.session.query(post.id, post.title,post.status)
        return results
    
    def getuserlist(self):
        results= self.session.query(users.id, users.username, users.role)
        return results

    def giveadmin(self,userid):
        res=self.session.query(users).filter(users.id==userid).first()
        if not res:
            return False
        res.role='admin'
        self.session.commit()
        return True
    
    def giveuser(self,userid):
        res=self.session.query(users).filter(users.id==userid).first()
        if not res:
            return False
        res.role='user'
        self.session.commit()
        return True
    
    def givesuperadmin(self,userid):
        res=self.session.query(users).filter(users.id==userid).first()
        if not res:
            return False
        res.role='superadmin'
        self.session.commit()
        return True


    def getpost(self,postid):
        res=self.session.query(post).filter(post.id==postid).first()
        return res
    def checkid(self,userid,status=''):
        res=self.session.query(users).filter(users.id==userid).first()
        if(not res):
            return False
        if res.role !=status:
            return False
        return True
    
    def review(self,postid,status):
        print(status)
        res=self.session.query(post).filter(post.id==postid).first()
        if not res:
            return False
        res.status=status
        self.session.commit()
        return True
    
    def createtoken(self, userid):
        """
        根据userid创建token并插入到数据库
        :param userid: 用户ID
        :return: 生成的token字符串
        """
        # 生成随机盐值
        salt = secrets.token_hex(16)
        
        # 创建哈希值：userid + 当前时间戳 + 随机盐值
        current_time = str(datetime.now().timestamp())
        hash_input = f"{userid}_{current_time}_{salt}"
        
        # 生成SHA256哈希值作为token
        token = hashlib.sha256(hash_input.encode()).hexdigest()
        
        # 设置时间
        created_time = datetime.now()
        expires_time = created_time + timedelta(days=1)  # 一天后过期
        
        try:
            # 创建新的token记录
            new_token = Token(
                token=token,
                expires_at=expires_time,
                created_at=created_time
            )
            
            # 假设self.session是数据库会话对象
            self.session.add(new_token)
            self.session.commit()
            
            return token
            
        except Exception as e:
            self.session.rollback()
            raise Exception(f"创建token失败: {str(e)}")
        
    def recordlog(self,user_id,log_type,content,ip):
        """
        记录日志
        :param user_id: 用户ID
        :param log_type: 日志类型，'access','error','behavior','system'
        :param content: 日志内容
        :param ip: IP地址
        """
        try:
            new_log = Log(
                user_id=user_id,
                type=log_type,
                content=content,
                ip=ip
            )
            self.session.add(new_log)
            self.session.commit()
        except Exception as e:
            self.session.rollback()
            raise Exception(f"记录日志失败: {str(e)}")
    
    def getrecordlog(self):
       res= self.session.query(Log).all()
       return res 
    
    def recordsyscost(self, endpoint: str, elapsed_time: float, cpu_user: float, cpu_system: float, memory_rss: int):
        """
        记录系统性能消耗到 performance_data 表
        :param endpoint: 请求接口路径
        :param elapsed_time: 总耗时（秒）
        :param cpu_user: 用户态 CPU 时间差（秒）
        :param cpu_system: 系统态 CPU 时间差（秒）
        :param memory_rss: RSS 内存增量（字节）
        """
        try:
            new_record = PerformanceData(
                endpoint=endpoint,
                elapsed_time=elapsed_time,
                cpu_user=cpu_user,
                cpu_system=cpu_system,
                memory_rss=memory_rss
            )
            self.session.add(new_record)
            self.session.commit()
        except Exception as e:
            self.session.rollback()
            raise Exception(f"记录系统性能消耗失败: {e}")
    
    def getsyscost(self):
        res= self.session.query(PerformanceData).all()
        return res