package com.neusoft.smart.pos.ota.service;

import com.neusoft.smart.pos.dto.ota.request.UpgradePackageQueryRequest;
import com.neusoft.smart.pos.dto.ota.request.UpgradePackageRequest;
import com.neusoft.smart.pos.dto.ota.request.UpgradeStrategyQueryRequest;
import com.neusoft.smart.pos.dto.ota.response.UpgradePackageResponse;
import com.neusoft.smart.pos.framework.exception.BusinessCommonException;
import com.neusoft.smart.pos.framework.task.TaskExecutor;
import com.neusoft.smart.pos.framework.utils.BeanUtil;
import com.neusoft.smart.pos.framework.utils.ExcelUtils;
import com.neusoft.smart.pos.ota.constants.OTAErrorCode;
import com.neusoft.smart.pos.ota.persistent.domain.UpgradePackage;
import com.neusoft.smart.pos.ota.persistent.ext.domain.UpgradePackageQuery;
import com.neusoft.smart.pos.ota.persistent.repository.UpgradePackageRepository;
import com.neusoft.smart.pos.ota.task.PackagesDeleteTask;
import com.neusoft.smart.pos.utils.RequestHeaderUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
public class UpgradePackageService {
    
    @Autowired
    private UpgradePackageRepository upgradePackageRepository;
    
    @Autowired
    private UpgradeStrategyService upgradeStrategyService;
    
    @Autowired
    private TaskExecutor taskExecutor;
    
    @Transactional
    public UpgradePackageResponse create(UpgradePackageRequest upgradePackageRequest) {
        String version = upgradePackageRequest.getVersionCode();
        //版本验证规则 编译正则表达式
        Pattern pattern = Pattern.compile("^[0-9]+\\.[0-9]+\\.[0-9]+$");
        Pattern patternPDA = Pattern.compile("^[0-9]+\\_[0-9]+$");
        Matcher matcher = pattern.matcher(version);
        if (upgradePackageRequest.getFileType().equals(2)) {
            matcher = patternPDA.matcher(version);
        }
        // 字符串是否与正则表达式相匹配
        if (!matcher.matches()) {
            throw new BusinessCommonException(OTAErrorCode.VERSION_FORMAT_ERROR);
        }
//		String versionSuffix = upgradePackageRequest.getVersionCode().substring(upgradePackageRequest.getVersionCode().lastIndexOf(".") + 1);
        UpgradePackageQuery upgradePackageQuery = new UpgradePackageQuery();
        upgradePackageQuery.setVersionCode(upgradePackageRequest.getVersionCode());
        upgradePackageQuery.setStatusArr(new Integer[]{0});
        Integer count = upgradePackageRepository.queryCount(upgradePackageQuery);
        if (count > 0) {
            throw new BusinessCommonException(OTAErrorCode.VERSION_DUPLICATE);
        }
        UpgradePackage upgradePackage = new UpgradePackage();
        BeanUtils.copyProperties(upgradePackageRequest, upgradePackage);
        upgradePackage.setCreatedBy(RequestHeaderUtil.getUserId());
        upgradePackage.setOrganizationId(RequestHeaderUtil.getOrgId());
        upgradePackage.setCreatedDate(new Date());
        upgradePackage = upgradePackageRepository.create(upgradePackage);
        UpgradePackageResponse response = new UpgradePackageResponse();
        BeanUtils.copyProperties(upgradePackage, response);
        return response;
    }
    
    /**
     * @param packageId
     */
    public void delete(Integer packageId) {
        UpgradeStrategyQueryRequest upgradeStrategyQueryRequest = new UpgradeStrategyQueryRequest();
        upgradeStrategyQueryRequest.setPackageId(packageId);
        upgradeStrategyQueryRequest.setStatus(0);
        Integer count = upgradeStrategyService.queryGroupCount(upgradeStrategyQueryRequest);
        if (count > 0) {
            throw new BusinessCommonException(OTAErrorCode.CAN_NOT_DELETE);
        }
        upgradePackageRepository.delete(packageId);
        PackagesDeleteTask packagesDeleteTask = new PackagesDeleteTask();
        packagesDeleteTask.setPackageId(packageId);
        taskExecutor.getExecutorService().submit(packagesDeleteTask);
    }
    
    /**
     * @param upgradePackageQueryRequest
     * @return
     */
    public List<UpgradePackageResponse> getList(UpgradePackageQueryRequest upgradePackageQueryRequest) {
        List<UpgradePackageResponse> result = new ArrayList<>();
        List<UpgradePackage> poList = upgradePackageRepository.queryList(BeanUtil.parse(upgradePackageQueryRequest, UpgradePackageQuery.class));
        poList.forEach(po -> {
            UpgradePackageResponse response = new UpgradePackageResponse();
            BeanUtils.copyProperties(po, response);
            result.add(response);
        });
        return result;
    }
    
    /**
     * @param upgradePackageQueryRequest
     * @return
     */
    public Integer queryCount(UpgradePackageQueryRequest upgradePackageQueryRequest) {
        return upgradePackageRepository.queryCount(BeanUtil.parse(upgradePackageQueryRequest, UpgradePackageQuery.class));
    }
    
    /**
     * @param pacakgeId
     * @return
     */
    public UpgradePackageResponse get(Integer pacakgeId) {
        UpgradePackage upgradePackage = upgradePackageRepository.get(pacakgeId);
        UpgradePackageResponse response = new UpgradePackageResponse();
        BeanUtils.copyProperties(upgradePackage, response);
        return response;
    }
    
    
    public void export(UpgradePackageQueryRequest upgradePackageQueryRequest, OutputStream os) throws Exception {
        if (!"sa".equals(RequestHeaderUtil.getRole())) {
            upgradePackageQueryRequest.setOrganizationId(RequestHeaderUtil.getOrgId());
        }
        upgradePackageQueryRequest.setIsPage(false);
        upgradePackageQueryRequest.setStatusArr(new Integer[]{0, 1, 2});
        List<UpgradePackage> poList = upgradePackageRepository.queryList(BeanUtil.parse(upgradePackageQueryRequest, UpgradePackageQuery.class));
        
        List<String> fieldNames = Arrays.asList("文件名", "路径", "MD5", "大小", "版本", "厂商", "设备", "型号", "客户", "包类型", "ReleaseNote");
        
        List<List<Object>> fieldData = poList.stream().map(upgradePackage -> {
            List<Object> objectList = new ArrayList<>();
            objectList.addAll(Arrays.asList(upgradePackage.getFileName(), upgradePackage.getFilePath(), upgradePackage.getMd5Code(), upgradePackage.getFileSize(), upgradePackage.getVersionCode(), upgradePackage.getManufacturer(),
                    upgradePackage.getDeviceType(), upgradePackage.getDeviceModel(), upgradePackage.getCustomer(), new Integer(1).equals(upgradePackage.getFileType()) ? "全量包" : "增量包", upgradePackage.getReleaseNote()));
            return objectList;
        }).collect(Collectors.toList());
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ExcelUtils.exportExcel(fieldNames, fieldData, outputStream);
        os.write(outputStream.toByteArray());
        os.flush();
        os.close();
    }
}
