package com.mvc.service.upgrade;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mvc.constant.PathConstant;
import com.mvc.constant.UpgradePlanStatus;
import com.mvc.dao.TUpgradePackageMapper;
import com.mvc.entity.TUpgradePackage;
import com.mvc.entity.TUpgradePackageExample;
import com.mvc.entity.TUpgradePlan;
import com.mvc.model.ResPageModel;
import com.mvc.model.upgrade.TUpgradePackageModel;
import com.mvc.netty.dealconstant.ResourceTag;
import com.mvc.utils.DiffUtil;
import com.mvc.utils.FileUtil;
import com.mvc.utils.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class TUpgradePackageService {

    @Resource
    private TUpgradePackageMapper tUpgradePackageMapper;

    @Resource
    private Environment env;

    @Resource
    private TUpgradePlanService tUpgradePlanService;

    /**
     * 获取原始文件包列表(未经过差分的)
     *
     * @return
     */
    public List<TUpgradePackageModel> findOriginalPackageList(TUpgradePackageModel queryModel) {
        TUpgradePackageExample example = new TUpgradePackageExample();
        TUpgradePackageExample.Criteria criteria = example.createCriteria();
        if(StringUtils.isNotEmpty(queryModel.getOriginalNewFileName())){
            criteria.andOriginalNewFileNameLike(StringUtil.getLikeFormat(queryModel.getOriginalNewFileName()));
        }
        criteria.andOldFileNameIsNotNull();
        example.setOrderByClause(" CREATE_TIME desc ");
        PageHelper.startPage(1, 50);
        List<TUpgradePackage> tUpgradePackages = tUpgradePackageMapper.selectByExample(example);
        List<TUpgradePackageModel> resList = new ArrayList<>();
        List<String> tempList = new ArrayList<>();
        for (TUpgradePackage upgradePackage : tUpgradePackages) {
            //数据转换,一条记录的新旧版本转换为两条,并去除重复
            if (!tempList.contains(upgradePackage.getOriginalOldFileName())) {
                TUpgradePackageModel model = new TUpgradePackageModel();
                model.setId(upgradePackage.getId());
                model.setFileName(upgradePackage.getOldFileName());
                model.setOriginalFileName(upgradePackage.getOriginalOldFileName());
                tempList.add(upgradePackage.getOriginalOldFileName());
                //tempList.add(upgradePackage.getOldFileName());
                resList.add(model);
            }

            if (!tempList.contains(upgradePackage.getOriginalNewFileName())) {
                TUpgradePackageModel model = new TUpgradePackageModel();
                model.setId(upgradePackage.getId());
                model.setFileName(upgradePackage.getNewFileName());
                model.setOriginalFileName(upgradePackage.getOriginalNewFileName());
                tempList.add(upgradePackage.getOriginalNewFileName());
                //tempList.add(upgradePackage.getNewFileName());
                resList.add(model);
            }
        }
        return resList;
    }

    /**
     * 分页查询全部记录
     *
     * @param queryModel
     * @return
     */
    public ResPageModel findAllTUpgradePackage(TUpgradePackageModel queryModel) {
        TUpgradePackageExample example = new TUpgradePackageExample();
        TUpgradePackageExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotEmpty(queryModel.getOriginalFileName())) {
            criteria.andOriginalFileNameLike(StringUtil.getLikeFormat(queryModel.getOriginalFileName()));
        }
        if (StringUtils.isNotEmpty(queryModel.getVersionNum())) {
            criteria.andVersionNumLike(StringUtil.getLikeFormat(queryModel.getVersionNum()));
        }
        if (StringUtils.isNotEmpty(queryModel.getUpdateContent())) {
            criteria.andUpdateContentLike(StringUtil.getLikeFormat(queryModel.getUpdateContent()));
        }
        if (StringUtils.isNotEmpty(queryModel.getFileType())) {
            criteria.andFileTypeEqualTo(queryModel.getFileType());
        }

        example.setOrderByClause(" CREATE_TIME desc ");

        Page<Object> pageObject = PageHelper.startPage(queryModel.getPageNum(), queryModel.getPageSize());
        List<TUpgradePackage> tUpgradePackages = tUpgradePackageMapper.selectByExample(example);
        List<TUpgradePackageModel> resList = new ArrayList<>();
        for (TUpgradePackage tUpgradePackage : tUpgradePackages) {
            TUpgradePackageModel model = new TUpgradePackageModel();
            BeanUtils.copyProperties(tUpgradePackage, model);
            setFileUrl(model);
            resList.add(model);
        }
        ResPageModel resPageModel = new ResPageModel(resList, pageObject);
        return resPageModel;
    }

    /**
     * 设置前台的下载链接
     *
     * @param model
     */
    private void setFileUrl(TUpgradePackageModel model) {
        String url = env.getProperty(ResourceTag.ResourceUrlTag.getTag()) + "/download/"
                + PathConstant.DIR_UPGRADE_PACKAGE
                + PathConstant.DIR_UPGRADE_PACKAGE_MCU
                + model.getFileName();
        model.setFileUrl(url);
    }

    /**
     * 保存新增对象
     *
     * @param model
     * @return
     */
    public TUpgradePackageModel saveTUpgradePackage(TUpgradePackageModel model) {
        model.setCreateTime(new Date());

        if (StringUtils.isEmpty(model.getFileName())) {
            setDiffPackage(model);
        }

        TUpgradePackage tUpgradePackage = new TUpgradePackage();
        BeanUtils.copyProperties(model, tUpgradePackage);
        int insert = tUpgradePackageMapper.insert(tUpgradePackage);
        model.setId(tUpgradePackage.getId());
        return model;
    }

    private void setDiffPackage(TUpgradePackageModel model) {
        String guid = StringUtils.isEmpty(model.getGuid())?StringUtil.getUuid():model.getGuid();
        String rootPath = env.getProperty(ResourceTag.DownloadPathTag.getTag()) + PathConstant.DIR_UPGRADE_PACKAGE + PathConstant.DIR_UPGRADE_PACKAGE_MCU;
        String ext = FileUtil.getFileExtension(model.getNewFileName());
        String oldFullFileName = rootPath + model.getOldFileName();
        String newFileName = rootPath + model.getNewFileName();
        String diffFileName = rootPath + guid + ext;
        if (DiffUtil.generateDiff(oldFullFileName, newFileName, diffFileName)) {
            File diffFile = new File(diffFileName);
            model.setFileName(guid + ext);
            model.setFileSize((int) diffFile.length() / 1024);
            //系统生成的差分文件,命名(旧版本原文件名_新版本号.bin)
            model.setOriginalFileName(String.format("%s_%s%s",model.getOriginalOldFileName().replace(ext,""),model.getVersionNum(),ext));
        }
    }

    /**
     * 修改对象
     *
     * @param model
     * @return
     */
    public TUpgradePackageModel updateTUpgradePackage(TUpgradePackageModel model) {
        TUpgradePackage tUpgradePackage = tUpgradePackageMapper.selectByPrimaryKey(model.getId());
        BeanUtils.copyProperties(model, tUpgradePackage);
        int i = tUpgradePackageMapper.updateByPrimaryKey(tUpgradePackage);
        return model;
    }

    /**
     * 删除对象
     *
     * @param id
     * @return
     */
    public int deleteTUpgradePackage(int id) {
        int i = tUpgradePackageMapper.deleteByPrimaryKey(id);
        if (i > 0) {
            tUpgradePlanService.deleteTUpgradePlanByPackageId(id);
        }
        return i;
    }

    /**
     * 根据ID获取对象
     *
     * @param id
     * @return
     */
    public TUpgradePackageModel findTUpgradePackageById(int id) {
        TUpgradePackageModel model = null;
        TUpgradePackage tUpgradePackage = tUpgradePackageMapper.selectByPrimaryKey(id);
        if (tUpgradePackage != null) {
            model = new TUpgradePackageModel();
            BeanUtils.copyProperties(tUpgradePackage, model);
        }
        return model;
    }

    /**
     * 上传升级包
     *
     * @param file
     * @return
     * @throws IOException
     */
    public TUpgradePackageModel uploadPackage(MultipartFile file) throws IOException {
        TUpgradePackageModel model = new TUpgradePackageModel();
        String uuid = StringUtil.getUuid();
        String ext = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));

        InputStream inputStream = file.getInputStream();

        String outPath = env.getProperty(ResourceTag.DownloadPathTag.getTag()) + PathConstant.DIR_UPGRADE_PACKAGE + PathConstant.DIR_UPGRADE_PACKAGE_MCU;
        //upgrade

        File outDir = new File(outPath);
        if (!outDir.exists()) {
            outDir.mkdirs();
        }
        outPath += uuid + ext;

        File outFile = new File(outPath);
        if (outFile.exists()) {
            outFile.delete();
        }
        outFile.createNewFile();
        OutputStream outputStream = new FileOutputStream(outPath);
        IOUtils.copy(inputStream, outputStream);
        outputStream.flush();
        inputStream.close();
        outputStream.close();
        model.setOriginalFileName(file.getOriginalFilename());
        model.setFileName(uuid + ext);
        int fileSize = (int) file.getSize() / 1024; //转KB
        model.setFileSize(fileSize);
        return model;
    }

    /**
     * 校验删除规则
     *
     * @param id
     * @return
     */
    public String verificationRules(int id) {
        List<TUpgradePlan> plans = tUpgradePlanService.findTUpgradePlanByPackageId(id);
        for (TUpgradePlan plan : plans) {
            if (plan.getPlanStatus().equals(UpgradePlanStatus.INCOMPLETE.getFlag())) {
                return "当前升级文件存在未完成的任务,不可删除";
            }
        }
        return null;
    }

    /**
     * 上传原始文件
     *
     * @param file
     * @return
     * @throws IOException
     */
    public TUpgradePackageModel uploadPackageOriginalFile(MultipartFile file, String param) throws IOException {
        TUpgradePackageModel model = new TUpgradePackageModel();
        boolean isOldFile = false;
        if (param.equals("0")) {//旧文件是上传的
            isOldFile = true;
            param = StringUtil.getUuid();
            model.setGuid(param);
        }else if(param.equals("1")){//旧文件是选择的
            param = StringUtil.getUuid();
            model.setGuid(param);
        }
        String ext = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));

        InputStream inputStream = file.getInputStream();
        String rootPath = env.getProperty(ResourceTag.DownloadPathTag.getTag()) + PathConstant.DIR_UPGRADE_PACKAGE + PathConstant.DIR_UPGRADE_PACKAGE_MCU;

        File outDir = new File(rootPath);
        if (!outDir.exists()) {
            outDir.mkdirs();
        }
        String fileName = param + (isOldFile ? "_0" : "_1") + ext;
        String outPath = rootPath + fileName;

        File outFile = new File(outPath);
        if (outFile.exists()) {
            outFile.delete();
        }
        outFile.createNewFile();
        OutputStream outputStream = new FileOutputStream(outPath);
        IOUtils.copy(inputStream, outputStream);
        outputStream.flush();
        inputStream.close();
        outputStream.close();
        if (isOldFile) {
            model.setOldFileName(fileName);
            model.setOriginalOldFileName(file.getOriginalFilename());
        } else {
            model.setGuid(param);
            model.setNewFileName(fileName);
            model.setOriginalNewFileName(file.getOriginalFilename());

            String oldFileName = fileName.replaceAll("_1", "_0");
            //String oldFullFileName = rootPath + oldFileName;
            model.setOldFileName(oldFileName);

            /*String newFileName = rootPath + model.getNewFileName();
            String diffFileName = rootPath + param + ext;
            if (DiffUtil.generateDiff(oldFullFileName, newFileName, diffFileName)) {
                File diffFile = new File(diffFileName);
                model.setFileName(param + ext);
                model.setFileSize((int) diffFile.length() / 1024);
            }*/
        }

        return model;
    }
}
