# -*- coding: utf-8 -*-
from json import loads
from os.path import join,basename
from traceback import format_exc
import oss2
import string,random,os
import time
from common.YmlConstant import minio_yml_path
from minio import Minio
from loguru import logger
from exception.CustomerException import ServiceException
from enums.ExceptionEnum import ExceptionType
from util.RWUtils import getConfigs
import filetype,cv2,io
import numpy as np

class MinioSdk:

    __slots__ = ('minioClient', '__request_id', '__config')

    def __init__(self, *args):
        base_dir, env, self.__request_id = args
        self.minioClient = None
        self.__config = getConfigs(join(base_dir, minio_yml_path % env))
        self.get_minioClient()

    def get_minioClient(self):
        if self.minioClient is None:
            self.minioClient = Minio(
                                    endpoint=self.__config["endpoint"],
                                    access_key=self.__config["access_key"],
                                    secret_key=self.__config["secret_key"],
                                    secure=self.__config["secure"]
                                )
                    
    def get_bucknetName_from_filename(self,localPath):
        if isinstance(localPath,np.ndarray):
            return self.__config["image_bucket"],'jpg'
        ret = filetype.guess(localPath)
        if 'video' in ret.mime:
            return self.__config["video_bucket"],ret.mime
        elif  'image' in ret.mime: 
            return self.__config["image_bucket"],ret.mime
        else:
            logger.warning("上传文件到格式不是图片，或者视频, requestId:{}", self.__request_id)
            return self.__config["image_bucket"],'.oth'
    def create_bucknet(self,bucketName):
        if not self.minioClient.bucket_exists(bucketName):
          self.minioClient.make_bucket(bucketName)
          
    def put_object(self, localPath, remotePath):
        #localPath--本地文件路径，带有后缀---或者是字节流
        #remotePath--远程文件的名字，不带文件夹，不带后缀（为了与原OSS保持一致）
        request_id = self.__request_id
        logger.info("开始上传文件到oss, requestId:{}", request_id)
        bucketName,mime = self.get_bucknetName_from_filename(localPath)

        self.create_bucknet(bucketName)
        if '/' not in remotePath:
            remoteUrl=join(request_id,remotePath  )
        else:     remoteUrl = remotePath
        max_retries = 3
        retry_count = 0
        while True:
            try:
                self.get_minioClient()
                
                if isinstance(localPath,np.ndarray):
                    image_bytes = io.BytesIO(localPath)
                    #image_bytes = localPath.tobytes()
                    # 上传图片数据流    
                    ret = self.minioClient.put_object(bucketName, remoteUrl,image_bytes, len(localPath))
                else:
                    if 'video' in mime:#
                        newLocalpath = os.path.join( os.path.dirname(localPath),   ''.join(random.sample(string.ascii_letters ,32))+'.mp4'    )
                        cmd1 = 'ffmpeg -i %s  -vcodec libx264 -acodec copy %s'%(localPath,   newLocalpath  )
                        os.system(cmd1 )
                        cmd2 = 'mv %s %s'%(newLocalpath,localPath )
                        os.system(cmd2 )
                    ret = self.minioClient.fput_object(bucketName, remoteUrl,localPath,content_type=mime)
                    #print('-----line72: mime:',mime) 
                
                #outurl='http://'+self.__config["endpoint"]+'/'+bucketName+'/'+remoteUrl
                outurl=self.__config["domain"]+'/'+bucketName+'/'+remoteUrl
                logger.info("上传文件到minio成功! requestId:{},bucketName:{},objectName:{},remoteUrl:{}", request_id,ret.bucket_name,ret.object_name,outurl)
                return outurl
            except Exception as e:
                retry_count += 1
                time.sleep(1)
                self.minioClient = None
                logger.info("上传文件到minio失败, 重试次数：{}, requestId:{}", retry_count, request_id)
                if retry_count > max_retries:
                    logger.error("上传文件到oss重试失败:{}, requestId:{}", format_exc(), request_id)
                    raise e

if __name__ == "__main__":

    base_dir, env, request_id = '/home/th/WJ/test/tuoheng_alg','test','1122334455667788'
    #localPath = '/home/th/WJ/data/XunHe/ai_online.mp4'
    localPath =  '/home/th/WJ/data/XunHe/ai_online_avc1.mp4'
    #localPath = '/home/th/WJ/DSP2/AIdemo2/images/cityRoad/DJI_0019_142.jpg'
        
    
    remotePath='or.mp4'
    minioSdk = MinioSdk(base_dir, env, request_id )
    
    ##上传cv2编码后的图像np数组
    #image_array = cv2.imread( localPath )
    #_, localPath = cv2.imencode('.jpg', image_array)
     
         
    minioSdk.put_object(localPath, remotePath)


    
    #http://minio.t-aaron.com:9000/image/1122334455667788/or_.oth
  
    #http://minio.t-aaron.com:9000/image/messageId/t2.jpg
    #messageId/t2.jpg'
    
    #   print(aa.get_play_info('6928821035b171ee9f3b6632b68f0102'))
