package com.sooka.common.upload;

import com.alibaba.fastjson.JSON;
import com.sooka.common.upload.bean.UploadBean;
import com.sooka.common.utils.ControllerUtil;
import com.sooka.common.utils.PathUtil;
import com.sooka.common.utils.QiniuUtil;
import com.sooka.common.utils.StrUtil;
import com.sooka.module.web.system.service.AttachmentService;
import com.sooka.module.web.system.vo.UserVo;
import com.sooka.mybatis.model.TSysAttachment;
import com.sooka.common.constant.CmsConst;
import com.sooka.common.exception.ApiException;
import jodd.datetime.JDateTime;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Date;
import java.util.UUID;

import static com.sun.org.apache.xerces.internal.impl.dv.util.Base64.decode;

/**
 * Description:
 *
 *
 * @create 2017-07-19
 **/
@Component
@Scope("prototype")
public class UploadComponent {

    @Autowired
    private AttachmentService attachmentService;

    @Value("${enable.virtual.path}")
    String enableVirtualPath;

    @Value("${windows.file.upload.path}")
    String windowsUploadPath;

    @Value("${linux.file.upload.path}")
    String linuxUploadPath;

    @Value("${qiniu.access.key}")
    private String accessKey;

    @Value("${qiniu.secret.key}")
    private String secretKey;

    @Value("${qiniu.bucketname}")
    private String bucketname;

    @Value("${qiniu.cdn.domain}")
    private String domain;

    @Value("${qiniu.upload.on}")
    private String qiniuUpload;



    public UploadBean uploadFile(MultipartFile multipartFile, HttpServletRequest request){
        TSysAttachment attachment = new TSysAttachment();
        /** 获取用户会话 **/
        UserVo userVo  = (UserVo)request.getSession().getAttribute(CmsConst.SITE_USER_SESSION_KEY);
        if(userVo!=null) {
            attachment.setUserId(userVo.getUserId().toString());
            attachment.setUsername(userVo.getUsername());
        }
        attachment.setUploadDate(new Date());
        attachment.setUploadIp(ControllerUtil.getRemoteAddress(request));
        attachment.setFileSize(Float.valueOf(multipartFile.getSize())/1024);
        attachment.setFileExtname(multipartFile.getContentType());
        attachment.setFileKey(UUID.randomUUID().toString().replace("-",""));
        attachment.setOriginalFilename(multipartFile.getOriginalFilename());
        /*创建uploadBean*/
        UploadBean result = new UploadBean();
        String fileType = this.getFileType(attachment.getOriginalFilename());
        String fileName = this.getFileName(fileType) ;
        String newName =this.getNewFileName(fileName);

        if (!multipartFile.isEmpty()) {
            if (!Boolean.parseBoolean(qiniuUpload)) {
                File file = new File(this.getUploadPath() + newName);
                /*如果不存在就创建*/
                if (!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }
                try {
                    this.writeFile(multipartFile.getBytes(), file);
                    attachment.setFilePath(newName);
                    attachment.setFileName(fileName);
                    result.setFileUrl(request.getScheme() + "://" + ControllerUtil.getDomain() + "/res/" + attachment.getFileKey() + "." + fileType);
                    attachmentService.save(attachment);
                } catch (Exception e) {
                    throw new ApiException(e.getMessage());
                }
            }else {
                String qiniuFileResult = QiniuUtil.upload(accessKey, secretKey, bucketname, multipartFile);
                if (!StrUtil.isBlank(qiniuFileResult)) {
                    String fileKey = JSON.parseObject(qiniuFileResult).getString("key");
                    String fileUrl = domain + "/" + fileKey;
                    if (StrUtil.getExtensionName(fileName).equals("jpg") || StrUtil.getExtensionName(fileName).equals("JPG") || StrUtil.getExtensionName(fileName).equals("png") || StrUtil.getExtensionName(fileName).equals("PNG") || StrUtil.getExtensionName(fileName).equals("jpeg") || StrUtil.getExtensionName(fileName).equals("JPEG")) {
                        fileUrl += "?imageslim";
                    }
                    result.setFileUrl(fileUrl);
                }
            }
            return result;
        }else{
            throw new ApiException("上传文件不能为空！");
        }
    }

    public String getUploadPath(){
        String os = System.getProperty("os.name");
        String uploadPath = enableVirtualPath.equals("true")
                ?(os.toLowerCase().startsWith("win")
                ?windowsUploadPath
                :linuxUploadPath)
                : PathUtil.getRootClassPath()+ File.separator + "static";
        return uploadPath;
    }

    public  UploadBean uploadBase64File(String data, HttpServletRequest request){

        /*创建uploadBean*/
        UploadBean result = new UploadBean();
        if (!StringUtils.isBlank(data)) {
            TSysAttachment attachment = new TSysAttachment();
            UserVo userVo  = (UserVo)request.getSession().getAttribute(CmsConst.SITE_USER_SESSION_KEY);
            if(userVo!=null) {
                attachment.setUserId(userVo.getUserId().toString());
                attachment.setUsername(userVo.getUsername());
            }
            attachment.setUploadDate(new Date());
            attachment.setUploadIp(ControllerUtil.getRemoteAddress(request));
            attachment.setFileSize(this.getBase64FileSize(data).floatValue()/1024);
            if(getBase64FileType(data).equals("png")){
               attachment.setFileExtname("image/png");
            }else if(getBase64FileType(data).equals("gif")){
                attachment.setFileExtname("image/gif");
            }else if(getBase64FileType(data).equals("jpg")){
                attachment.setFileExtname("image/jpeg");
            }
            attachment.setFileKey(UUID.randomUUID().toString().replace("-",""));
           String fileType = this.getBase64FileType(data);
           String fileName = this.getFileName(fileType);
           String newName = this.getNewFileName(fileName);
            attachment.setOriginalFilename(newName);
            File file = new File(this.getUploadPath() + newName);
            attachment.setFilePath(file.getPath());
            attachment.setFileName(fileName);
            /*如果不存在就创建*/
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            try {
                this.writeFile(this.base64StrToByte(data),file);
            } catch (Exception e) {
                throw  new ApiException(e.getMessage());
            }
            result.setFileUrl(request.getScheme()+"://"+ ControllerUtil.getDomain()+ "/res/"+attachment.getFileKey()+"."+fileType);
            attachmentService.save(attachment);
            return result;
        }else{
                throw new ApiException("上传文件不能为空！");
        }
    }

    public  String getFileName(String fileType){
      return UUID.randomUUID().toString().replace("-","") + "." + fileType;
    }

    public  String getNewFileName(String fileName){
        JDateTime jt = new JDateTime();
        return File.separator + "upload" + File.separator + jt.getYear()
                + File.separator + jt.getMonth() + File.separator + jt.getDay() + File.separator + fileName;
    }

    public  String getFileType(String fileName) {
        String type = fileName.substring(fileName.lastIndexOf(".") + 1);
        return type;
    }

    /***
     * data:,文本数据
     data:text/plain,文本数据
     data:text/html,HTML代码
     data:text/html;base64,base64编码的HTML代码
     data:text/css,CSS代码
     data:text/css;base64,base64编码的CSS代码
     data:text/JavaScript,Javascript代码
     data:text/javascript;base64,base64编码的Javascript代码
     data:image/gif;base64,base64编码的gif图片数据
     data:image/png;base64,base64编码的png图片数据
     data:image/jpeg;base64,base64编码的jpeg图片数据
     data:image/x-icon;base64,base64编码的icon图片数据
     */
    public  String getBase64FileType(String data) {
       String fileType = data.split(",")[0];
       System.out.println(fileType);
       if("data:image/png;base64".equals(fileType)){
           return "png";
       }
       if("data:image/gif;base64".equals(fileType)){
            return "gif";
       }
        if("data:image/jpeg;base64".equals(fileType)){
            return "jpeg";
        }
       throw new ApiException("对不起，请上传正确的文件格式[.png,.gif,.jpg]");
    }

    private Integer getBase64FileSize(String data){
        String str = data.split(",")[1];
        Integer  equalIndex= str.indexOf("=");
        if(str.indexOf("=")>0) {
            str=str.substring(0, equalIndex);
        }
        Integer strLength=str.length();
       return strLength-(strLength/8)*2;
    }

    private byte[] base64StrToByte(String data){
        byte[] b ;
        b = decode(data.split(",")[1]);
        for (int i = 0; i < b.length; ++i) {
            if (b[i] < 0) {// 调整异常数据
                b[i] += 256;
            }
        }
        return b;
    }

    private synchronized void writeFile(byte[] bytes,File file) throws Exception{
        BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(file));
        stream.write(bytes);
        stream.close();
    }


    public static void  main(String[] args){
        UploadComponent uploadComponent = new UploadComponent();
        String s  = "1502176167115.png";
        System.out.println(s.contains("pngs"));
        uploadComponent.getBase64FileSize("data:image/jpeg;base64,[encoded data, 37024 characters]");
    }
}
