from os import path, makedirs
import json
from .VersionInfo import VersionInfo
from sqlalchemy import func


class VersionManager:
    
    def __init__(self, dbsession):
        self.__db = dbsession

    def AddVersion(self, verInfo, packageData, settings):
        if not isinstance(verInfo, VersionInfo):
            return None
        server_file_name = verInfo.VersionNo + '.zip'
        verInfo.Package = VersionManager._SavePackage(server_file_name, packageData, settings)
        self.__db.add(verInfo)
        
        return verInfo
        
        
    bucket_name = 'update-online'
    access_key_id = 'LTAI4YCzRAOIaA6v'
    access_key_secret = 'thUkHSGun0Ant797JsJexcZlSV3X0a'

    @staticmethod
    def _SavePackage(fileName, data, settings):
        oss_url = settings.get('update.base_url')
        local_path = settings.get('update.base_path')
        if oss_url:
            import oss2

            bucket = oss2.Bucket(oss2.Auth( \
                VersionManager.access_key_id, \
                VersionManager.access_key_secret), \
                oss_url, \
                VersionManager.bucket_name)

            bucket.put_object(fileName, data)

            return fileName
        elif local_path:
            pathName = path.join(local_path, fileName)
            with open(pathName, 'wb') as file:
                file.write(data)
            return fileName
        else:
            raise Exception('VersionManager: no location to save package.')
            
    @staticmethod
    def TransToOSSUrl(fileName, settings):
        oss_url = settings.get('update.base_url')
        if not oss_url:
            return fileName
        return 'http://%s.%s/%s' % (VersionManager.bucket_name, oss_url, fileName)
    
    def ListVersions(self, beginNo='', cnt=0):
        if beginNo:
            q = self.__db.query(VersionInfo).filter(VersionInfo.VersionNo>=beginNo)
        else:
            q = self.__db.query(VersionInfo)
        if cnt>0:
            q = q.limit(cnt)
        return q.all()
    
    def GetLatestVersion(self):
        verNo = self.__db.query(func.max(VersionInfo.VersionNo)).one_or_none()
        if not verNo:
            return None
        verNo = verNo[0]
        return self.__db.query(VersionInfo).filter(VersionInfo.VersionNo == verNo).one_or_none()
    
    def GetVersion(self, verNo):
        return self.__db.query(VersionInfo).filter(VersionInfo.VersionNo == verNo).one_or_none()
    
    def GetVersionPackage(self, verNo):
        dbver = self.GetVersion(verNo)
        return dbver.Package
    
    def GetPackageSizeByVerNo(self, verNo, settings):
        dbver = self.GetVersion(verNo)
        if not dbver:
            return 0
        return VersionManager.GetPackageSize(dbver, settings)
    
    @staticmethod
    def GetPackageSize(version, settings):
        oss_url = settings.get('update.base_url')
        local_path = settings.get('update.base_path')
        if oss_url:
            import oss2
            bucket = oss2.Bucket(oss2.Auth( \
                VersionManager.access_key_id, \
                VersionManager.access_key_secret), \
                oss_url, \
                VersionManager.bucket_name)
            return bucket.head_object(version.Package).content_length
        elif local_path:
            pathName = path.join(local_path, version.Package)
            return path.getsize(pathName)
        else:
            raise Exception('VersionManager: no this version No.')
