package com.bocloud.ims.service.internal.worker;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.model.NotifyMessage;
import com.bocloud.common.encrypt.AESEncrptor;
import com.bocloud.common.encrypt.Encryptor;
import com.bocloud.common.enums.BoCloudExchange;
import com.bocloud.common.enums.BoCloudMethod;
import com.bocloud.common.enums.BoCloudService;
import com.bocloud.common.enums.PostDataFormat;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.BocloudToken;
import com.bocloud.common.model.OperateResult;
import com.bocloud.common.model.OperateResult.OperateCategory;
import com.bocloud.common.model.RequestContext;
import com.bocloud.common.ssh.SshClient;
import com.bocloud.common.utils.ListTool;
import com.bocloud.common.utils.MapTools;
import com.bocloud.ims.entity.resource.CloudServer;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.ResourceEvent;
import com.bocloud.ims.entity.resource.Volume;
import com.bocloud.ims.repository.resource.CloudServerRepository;
import com.bocloud.ims.repository.resource.ResourceEventRepository;
import com.bocloud.ims.repository.resource.VolumeRepository;
import com.bocloud.ims.service.utils.ResourceEventPublisher;
import com.bocloud.service.core.CurrentService;
import com.bocloud.service.http.core.ServiceFactory;
import com.bocloud.service.http.model.RemoteService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.io.*;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * LVM创建任务
 *
 * @author wangyu
 * @version 1.0
 * @since 2020年4月28日
 */
@Component
public class LvmService {

    private static OperateCategory operateCategory = OperateCategory.ResourceEvent;
    private static Logger logger = LoggerFactory.getLogger(LvmService.class);
    @Autowired
    private ServiceFactory serviceFactory;
    @Autowired
    private CurrentService currentService;
    @Autowired
    private ResourceEventRepository resourceEventRepository;
    @Autowired
    private AmqpAdmin amqpAdmin;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private VolumeRepository volumeRepository;
    @Autowired
    private ResourceEventPublisher resourceEventPublisher;
    @Autowired
    private CloudServerRepository cloudServerRepository;
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    /**
     * 修改大小
     *
     * @param server
     * @param vendor
     * @param resizeDisk
     * @param volume
     * @param context
     * @return
     */
    public BocloudResult lvmResize(CloudServer server, CloudVendor vendor, JSONObject resizeDisk, Volume volume,
                                   RequestContext context) {
        try {
            Boolean forceMount =
                    null == resizeDisk.getBoolean("forceMount") ? false : resizeDisk.getBoolean("forceMount");
            String device = volume.getLvmMntp();
            Map<String, Object> params = new HashMap<>();
            Map<String, Object> module = new HashMap<>();
            Map<String, Object> args = new HashMap<>();
            args.put("resize", true);
            args.put("current_disk", volume.getDevice());
            args.put("resize_vgname", "vg" + device.replaceAll("/", "_"));
            args.put("resize_lvname", "lv" + device.replaceAll("/", "_"));
            args.put("lvextend_options", "-l +100%FREE");
            args.put("filesystem", StringUtils.isEmpty(volume.getFileSystem()) ? "ext4" : volume.getFileSystem());
            args.put("force_mount", forceMount);
            module.put("args", args);
            module.put("name", "bocloud_lvm");
            Map<String, Object> options = new HashMap<>();
            options.put("become", true);
            module.put("options", options);
            params.put("targets", buildTargets(server));
            params.put("module", module);
            // 提交任务
            BocloudResult<List<JSONObject>> result = this.callWorker(vendor, server, params, context, Operation.resize);
            Assert.isTrue(result.isSuccess(), result.getMessage());
            ResourceEvent event = new ResourceEvent(server.getId(), "扩容LVM容量", "成功", context.getTarget(), new Date(),
                    "VM", vendor.getId(), context.getCatalog());
            resourceEventRepository.save(event);
            return new BocloudResult(true, "Resize LVM成功");
        } catch (Exception e) {
            logger.info("Get error message：{}", e.getMessage());
            return new BocloudResult(false, e.getMessage());
        }
    }

    /**
     * lvm扩展
     *
     * @param server
     * @param vendor
     * @param editDisk
     * @param volume
     * @param context
     * @return
     */
    public BocloudResult lvmExtend(CloudServer server, CloudVendor vendor, JSONObject editDisk, Volume volume,
                                   RequestContext context) {
        try {
            Boolean forceMount = null == editDisk.getBoolean("forceMount") ? false : editDisk.getBoolean("forceMount");
            String device = editDisk.getString("device");
            Assert.notNull(device, "挂载点为空");
            Map<String, Object> params = new HashMap<>();
            Map<String, Object> module = new HashMap<>();
            Map<String, Object> args = new HashMap<>();
            args.put("extend", true);
            List<Volume> dataDisks = volumeRepository.listDataDisks(server.getId());
            StringBuilder builder = new StringBuilder();
            for (Volume dataDisk : dataDisks) {
                if (!StringUtils.isEmpty(dataDisk.getDevice()) && !StringUtils.isEmpty(dataDisk.getLvmMntp())
                        && dataDisk.getLvmMntp().equalsIgnoreCase(device)) {
                    builder.append(dataDisk.getDevice()).append(",");
                }
            }
            String currentDisks = builder.toString();
            if (currentDisks.lastIndexOf(",") > 0) {
                currentDisks = currentDisks.substring(0, currentDisks.lastIndexOf(","));
            }
            args.put("current_disk", currentDisks);
            List<Map<String, Object>> pvss = new ArrayList<>();
            Map<String, Object> pvs = new HashMap<>();
            String scsiId = volume.getVolumeUuid().replaceAll("-", "").replaceAll(" ", "").trim().toLowerCase();
            pvs.put("scsi_id", scsiId);
            pvss.add(pvs);
            args.put("pvs", pvss);
            args.put("extend_vgname", "vg" + device.replaceAll("/", "_"));
            args.put("extend_lvname", "lv" + device.replaceAll("/", "_"));
            args.put("lvextend_options", "-l +100%FREE");
            args.put("filesystem", StringUtils.isEmpty(volume.getFileSystem()) ? "ext4" : volume.getFileSystem());
            args.put("force_mount", forceMount);
            module.put("args", args);
            module.put("name", "bocloud_lvm");
            Map<String, Object> options = new HashMap<>();
            options.put("become", true);
            module.put("options", options);
            params.put("targets", buildTargets(server));
            params.put("module", module);
            // 提交任务
            BocloudResult<List<JSONObject>> result = this.callWorker(vendor, server, params, context, Operation.extend);
            Assert.isTrue(result.isSuccess(), result.getMessage());
            List<JSONObject> datas = result.getData();
            volume.setLvmMntp(device);
            volume.setForceMount(forceMount);
            volume.setMenderId(context.getTarget());
            volumeRepository.update(volume);
            List<Volume> volumes = volumeRepository.listByServerId(server.getId());
            for (Volume vol : volumes) {
                if (!StringUtils.isEmpty(vol.getVolumeUuid())) {
                    String volScsiId = vol.getVolumeUuid().replaceAll("-", "").replaceAll(" ", "").trim().toLowerCase();
                    for (JSONObject data : datas) {
                        String scsi = data.getString("scsiId");
                        if (scsi.contains(volScsiId)) {
                            vol.setDevice(data.getString("device"));
                            vol.setMenderId(context.getTarget());
                            volumeRepository.update(vol);
                        }
                    }
                }
            }
            ResourceEvent event = new ResourceEvent(server.getId(), "LVM扩展", "成功", context.getTarget(), new Date(),
                    "VM", vendor.getId(), context.getCatalog());
            resourceEventRepository.save(event);
            return new BocloudResult(true, "创建LVM成功");
        } catch (Exception e) {
            logger.info("Get error message：{}", e.getMessage());
            return new BocloudResult(false, e.getMessage());
        }
    }

    /**
     * lvm创建
     *
     * @param server
     * @param vendor
     * @param addDisk
     * @param volume
     * @param context
     * @return
     */
    public BocloudResult lvmCreate(CloudServer server, CloudVendor vendor, JSONObject addDisk, Volume volume,
                                   RequestContext context) {
        try {
            Boolean forceMount = null == addDisk.getBoolean("forceMount") ? false : addDisk.getBoolean("forceMount");
            String device = addDisk.getString("device");
            Assert.notNull(device, "挂载点为空");
            Map<String, Object> params = new HashMap<>();
            Map<String, Object> module = new HashMap<>();
            Map<String, Object> args = new HashMap<>();
            args.put("create", true);
            List<Map<String, Object>> pvss = new ArrayList<>();
            Map<String, Object> pvs = new HashMap<>();
            String scsiId = volume.getVolumeUuid().replaceAll("-", "").replaceAll(" ", "").trim().toLowerCase();
            pvs.put("scsi_id", scsiId);
            pvss.add(pvs);
            args.put("pvs", pvss);
            args.put("new_mntp", addDisk.getString("device"));
            String vgname = "vg" + device.replaceAll("/", "_");
            args.put("create_vgname", vgname);
            String lvname = "lv" + device.replaceAll("/", "_");
            args.put("create_lvname", lvname);
            args.put("create_lvsize", "100%FREE");
            args.put("filesystem",
                    StringUtils.isEmpty(addDisk.getString("fileSystem")) ? "ext4" : addDisk.getString("fileSystem"));
            args.put("force_mount", forceMount);
            module.put("args", args);
            module.put("name", "bocloud_lvm");
            Map<String, Object> options = new HashMap<>();
            options.put("become", true);
            module.put("options", options);
            params.put("targets", buildTargets(server));
            params.put("module", module);
            // 提交任务
            BocloudResult<List<JSONObject>> result = this.callWorker(vendor, server, params, context, Operation.create);
            Assert.isTrue(result.isSuccess(), result.getMessage());
            List<JSONObject> datas = result.getData();
//            for (JSONObject data : datas) {
//                String device1 = data.getString("device");
//                if (device1.contains(vgname) && device1.contains(lvname)) {
//                    volume.setDevice(device1);
//                    volume.setMenderId(context.getTarget());
//                }
//            }
            volume.setLvmMntp(device);
            volume.setForceMount(forceMount);
            volume.setFileSystem(
                    StringUtils.isEmpty(addDisk.getString("fileSystem")) ? "ext4" : addDisk.getString("fileSystem"));
            volume.setMenderId(context.getTarget());
            volumeRepository.update(volume);

            List<Volume> volumes = volumeRepository.listByServerId(server.getId());
            for (Volume vol : volumes) {
                if (!StringUtils.isEmpty(vol.getVolumeUuid())) {
                    String volScsiId = vol.getVolumeUuid().replaceAll("-", "").replaceAll(" ", "").trim().toLowerCase();
                    for (JSONObject data : datas) {
                        String scsi = data.getString("scsiId");
                        if (scsi.contains(volScsiId)) {
                            vol.setDevice(data.getString("device"));
                            vol.setMenderId(context.getTarget());
                            volumeRepository.update(vol);
                        }
                    }
                }
            }
            ResourceEvent event = new ResourceEvent(server.getId(), "创建LVM", "成功", context.getTarget(), new Date(),
                    "VM", vendor.getId(), context.getCatalog());
            resourceEventRepository.save(event);
            return new BocloudResult(true, "创建LVM成功");
        } catch (
                Exception e) {
            logger.info("Get error message：{}", e.getMessage());
            return new BocloudResult(false, e.getMessage());
        }
    }

    /**
     * 创建lvm卷
     *
     * @param server
     * @param vendor
     * @param addDiskList
     * @param volumes
     * @param context
     * @return
     */
    public BocloudResult lvmCreate(CloudServer server, CloudVendor vendor, List<JSONObject> addDiskList,
                                   List<Volume> volumes, RequestContext context) {
        try {
            // 筛选掉原云主机上的数据盘
            List<Volume> filterVolumes = new ArrayList<>();
            if (volumes.size() > addDiskList.size()) {
                int index = volumes.size() - addDiskList.size();
                for (int i = index; i < volumes.size(); i++) {
                    filterVolumes.add(volumes.get(i));
                }
            } else {
                filterVolumes = volumes;
            }
            // 云主机新增的数据盘
            Map<Long, Volume> usedVolumeMap = new HashMap<>();
            Integer count = 0;
            Map<String, List<Volume>> addDiskMap = new HashMap<>();
            Map<String, Volume> volumeMap = new HashMap<>();
            for (JSONObject addDisk : addDiskList) {
                String device = addDisk.getString("device");
                Boolean forceMount =
                        null == addDisk.getBoolean("forceMount") ? false : addDisk.getBoolean("forceMount");
                if (StringUtils.isEmpty(device)) {
                    continue;
                }
                Integer disk = addDisk.getInteger("disk");
                Volume findVolume = null;
                for (Volume volume : filterVolumes) {
                    if (disk.intValue() == volume.getSize().intValue() && !usedVolumeMap.containsKey(volume.getId())) {
                        usedVolumeMap.put(volume.getId(), volume);
                        findVolume = volume;
                        break;
                    }
                }
                List<Volume> objects = addDiskMap.get(device);
                if (ListTool.isEmpty(objects)) {
                    objects = new ArrayList<>();
                }
                findVolume.setLvmMntp(device);
                findVolume.setForceMount(forceMount);
                findVolume.setFileSystem(addDisk.getString("fileSystem"));
                findVolume.setMenderId(context.getTarget());
                volumeRepository.update(findVolume);
                objects.add(findVolume);
                addDiskMap.put(device, objects);
                volumeMap.put(findVolume.getVolumeUuid().replaceAll("-", "").replaceAll(" ", "").trim().toLowerCase(),
                        findVolume);
            }
            List<Future<BocloudResult<List<JSONObject>>>> futures = new ArrayList<>();
            for (String device : addDiskMap.keySet()) {
                List<Volume> objects = addDiskMap.get(device);
                List<Map<String, Object>> pvss = new ArrayList<>();
                String fs = "ext4";
                Boolean forceMount = false;
                for (Volume volume : objects) {
                    Map<String, Object> pvs = new HashMap<>();
                    String scsiId = volume.getVolumeUuid().replaceAll("-", "").replaceAll(" ", "").trim().toLowerCase();
                    pvs.put("scsi_id", scsiId);
                    pvss.add(pvs);
                    if (!StringUtils.isEmpty(volume.getFileSystem())) {
                        fs = volume.getFileSystem();
                    }
                    if (null != volume.getForceMount()) {
                        forceMount = volume.getForceMount();
                    }
                }
                Map<String, Object> params = new HashMap<>();
                Map<String, Object> module = new HashMap<>();
                Map<String, Object> args = new HashMap<>();
                args.put("create", true);
                args.put("pvs", pvss);
                args.put("new_mntp", device);
                args.put("create_vgname", "vg" + device.replaceAll("/", "_"));
                args.put("create_lvname", "lv" + device.replaceAll("/", "_"));
                args.put("create_lvsize", "100%FREE");
                args.put("filesystem", fs);
                args.put("force_mount", forceMount);
                module.put("args", args);
                module.put("name", "bocloud_lvm");
                Map<String, Object> options = new HashMap<>();
                options.put("become", true);
                module.put("options", options);
                params.put("targets", buildTargets(server));
                params.put("module", module);
                // 提交任务
                Future<BocloudResult<List<JSONObject>>> future =
                        taskExecutor.submit(() -> this.callWorker(vendor, server, params, context, Operation.create));
                futures.add(future);
                count++;
            }
            for (int i = 0; i < futures.size(); i++) {
                Future<BocloudResult<List<JSONObject>>> future = futures.get(i);
                BocloudResult<List<JSONObject>> result = future.get(1, TimeUnit.HOURS);
                Assert.isTrue(result.isSuccess(), result.getMessage());
                List<JSONObject> datas = result.getData();
                // String mountPoint = "";
                // for (JSONObject data : datas) {
                // String scsi = data.getString("scsiId");
                // if (volumeMap.containsKey(scsi)) {
                // mountPoint = data.getString("device");
                // Volume volume = volumeMap.get(scsi);
                // volume.setDevice(mountPoint);
                // volume.setMenderId(context.getTarget());
                // volumeRepository.update(volume);
                // volumeMap.remove(scsi);
                // }
                // }
                List<Volume> allVolumes = volumeRepository.listByServerId(server.getId());
                for (Volume vol : allVolumes) {
                    if (!StringUtils.isEmpty(vol.getVolumeUuid())) {
                        String volScsiId =
                                vol.getVolumeUuid().replaceAll("-", "").replaceAll(" ", "").trim().toLowerCase();
                        for (JSONObject data : datas) {
                            String scsi = data.getString("scsiId");
                            if (scsi.contains(volScsiId)) {
                                vol.setDevice(data.getString("device"));
                                vol.setMenderId(context.getTarget());
                                volumeRepository.update(vol);
                            }
                        }
                    }
                }
            }
            ResourceEvent event = new ResourceEvent(server.getId(), "创建LVM卷", "成功", context.getTarget(), new Date(),
                    "VM", vendor.getId(), context.getCatalog());
            resourceEventRepository.save(event);
            return new BocloudResult(true, "创建LVM成功");
        } catch (Exception e) {
            logger.info("Get error message：{}", e.getMessage());
            return new BocloudResult(false, e.getMessage());
        }
    }

    /**
     * 构造目标服务器参数
     *
     * @param server
     * @return
     * @throws Exception
     */
    private List<Map<String, Object>> buildTargets(CloudServer server) throws Exception {
        String connectIp = null;
        Long start = System.currentTimeMillis();
        boolean flag = true;
        while (flag) {
            server = cloudServerRepository.query(server.getId());
            Assert.notNull(server, "云主机不存在");
            logger.info("数据库云主机ip对象：" + server.getPrivateIps());
            List<JSONObject> objects = JSONArray.parseArray(server.getPrivateIps(), JSONObject.class);
            List<String> ips = new ArrayList<>();
            for (JSONObject object : objects) {
                String address = object.getString("address");
                if (!StringUtils.isEmpty(address)) {
                    InetAddress ipAddress = InetAddress.getByName(address.trim());
                    if (ipAddress instanceof Inet4Address) {
                        ips.add(address);
                    }
                }
            }
            logger.info("获取到云主机所有ip：" + JSONObject.toJSONString(ips));
            // 设置等待超时时间为20分钟
            if (System.currentTimeMillis() - start > 20 * 1000 * 60) {
                flag = false;
                break;
            }
            for (String ip : ips) {
                SshClient sshClient = new SshClient(ip, "root", server.receivePswd(), 22);
                if (sshClient.connect()) {
                    connectIp = ip;
                    flag = false;
                    break;
                }
            }
        }
        Assert.notNull(connectIp, "云主机连接过程中发生错误");
        List<Map<String, Object>> targets = new ArrayList<>();
        Map<String, Object> target = new HashMap<>();
        target.put("category", "Linux");
        Encryptor encryptor = new AESEncrptor();
        target.put("pasd", encryptor.encrypt(server.receivePswd(), null));
        target.put("host", connectIp);
        target.put("user", "root");
        target.put("port", 22);
        targets.add(target);
        logger.info("云主机ip对象：" + JSONObject.toJSONString(target));
        return targets;
    }

    /**
     * @param vendor
     * @param spaceIds
     * @return com.bocloud.common.model.BocloudResult
     * @Author: lxy
     * @Description: lvm删除，调用worker
     * @Date 2021/6/25 17:48
     * @Param server
     * @throws:
     **/
    public BocloudResult lvmDelete(CloudServer server, CloudVendor vendor, List<String> spaceIds, RequestContext context) {
        try {
            Map<String, Object> module = new HashMap<>();
            Map<String, Object> args = new HashMap<>();
            args.put("delete", true);
            List<String> spaceIdsSend = spaceIds.stream().map(spaceId -> spaceId.replaceAll("-", "").replaceAll(" ", "").trim().toLowerCase()).collect(Collectors.toList());
            args.put("spaceIds", spaceIdsSend);

            module.put("args", args);
            module.put("name", "bocloud_lvm");
            Map<String, Object> options = new HashMap<>();
            options.put("become", true);
            module.put("options", options);
            Map<String, Object> params = new HashMap<>();
            params.put("targets", buildTargets(server));
            params.put("module", module);
            // 提交任务
            BocloudResult<List<JSONObject>> result = this.callWorker(vendor, server, params, context, Operation.delete);
            Assert.isTrue(result.isSuccess(), result.getMessage());
            ResourceEvent event = new ResourceEvent(server.getId(), "删除LVM", "成功", context.getTarget(), new Date(),
                    "VM", vendor.getId(), context.getCatalog());
            resourceEventRepository.save(event);
            return result;
        } catch (EOFException eofException) {
            logger.info("Get error message：{}", eofException.getMessage());
            return new BocloudResult(false, "删除lvm失败,云主机连接超时，原因：" + eofException.getMessage());
        } catch (IOException ioException) {
            logger.info("Get error message：{}", ioException.getMessage());
            return new BocloudResult(false, "删除lvm失败,云主机连接超时，原因：" + ioException.getMessage());
        } catch (Exception e) {
            logger.info("Get error message：{}", e.getMessage());
            return new BocloudResult(false, "删除lvm失败，原因：" + e.getMessage());
        }
    }

    public enum Operation {
        create, extend, resize, delete
    }

    /**
     * 调用worker执行lvm任务
     *
     * @param vendor
     * @param server
     * @param paramMap
     * @param context
     * @param operation
     * @return
     */
    public BocloudResult<List<JSONObject>> callWorker(CloudVendor vendor, CloudServer server,
                                                      Map<String, Object> paramMap, RequestContext context, Operation operation) {
        Map<String, Object> headers = MapTools.simpleMap("Content-Type", "application/json");
        headers.put(BocloudToken.INTERNAL_TOKEN, currentService.getToken());
        RemoteService remoteService = serviceFactory.build(BoCloudService.COP, "/v1/tasks/execute",
                BoCloudMethod.OPERATE, headers, paramMap);
        BocloudResult<List<JSONObject>> result = null;
        if (!remoteService.isExist()) {
            logger.error("远程Worker不存在!");
            return new BocloudResult<>(false, "远程Worker服务不存在！");
        }
        // 声明临时队列，用于获取worker执行结果
        String resultQueue = UUID.randomUUID().toString();
        amqpAdmin.declareQueue(new Queue(resultQueue, false, false, true));
        amqpAdmin.declareBinding(new Binding(resultQueue, Binding.DestinationType.QUEUE,
                BoCloudExchange.Default.DIRECT.getExchange(), resultQueue, null));

        JSONObject paramObject = new JSONObject();
        paramObject.put("queue", resultQueue);
        JSONObject oldParams = null;
        if (null == remoteService.getParam().getParams()) {
            oldParams = new JSONObject();
        } else {
            oldParams = JSONObject.parseObject(JSONObject.toJSONString(remoteService.getParam().getParams()));
        }
        if (oldParams.keySet().size() > 0) {
            paramObject.putAll(oldParams);
        }
        remoteService.getParam().setParams(paramObject);

        remoteService.setDataFormat(PostDataFormat.RAW);
        logger.info("LVM调用worker参数：{}，url路径为：{}，执行操作为：{}", JSONObject.toJSON(remoteService.getParam().getParams()), remoteService.getUrl(), operation.name());
        BocloudResult bocloudResult = remoteService.invoke();
        // 这里说明请求成功发送到worker上，接下来可以等待结果消息了
        if (bocloudResult.isSuccess()) {
            try {
                Message message = amqpTemplate.receive(resultQueue, 1000L * 60 * 30);
                if (null != message) {
                    String content = new String(message.getBody());
                    logger.info("Received Job result!,content {}", content);
                    JSONObject jsonObject = JSONObject.parseObject(content);
                    Boolean isSuccess = jsonObject.getBoolean("success");
                    if (isSuccess) {
                        if (Operation.create == operation || Operation.extend == operation || Operation.delete == operation) {
                            List<JSONObject> results =
                                    JSONArray.parseArray(jsonObject.getString("data"), JSONObject.class);
                            List<JSONObject> resultList = new ArrayList<>();
                            if (!ListTool.isEmpty(results)) {
                                JSONObject resultObj = results.get(0);
//                                JSONObject resMessage = JSONObject.parseObject(resultObj.getString("message"), JSONObject.class);
//                                Assert.notNull(resMessage, "LVM操作失败！获取worker执行结果resMessage为空，执行操作为：" + operation.name());
//                                JSONObject ansibleFacts = JSONObject.parseObject(resMessage.getString("ansible_facts"), JSONObject.class);
//                                Assert.notNull(ansibleFacts, "LVM操作失败！获取worker执行结果ansibleFacts为空，执行操作为：" + operation.name());
//                                List<JSONObject> ansibleMounts = JSONArray.parseArray(ansibleFacts.getString("ansible_mounts"), JSONObject.class);
//                                if (ListTool.isEmpty(ansibleMounts)) {
//                                    logger.error("LVM操作失败！获取worker执行结果ansibleMounts为空，执行操作为：" + operation.name());
//                                    result = new BocloudResult<>(false, "LVM操作失败！获取worker执行结果ansibleMounts为空，执行操作为：" + operation.name());
//                                }
//                                for (JSONObject mounts : ansibleMounts) {
//                                    JSONObject object = new JSONObject();
//                                    object.put("device", mounts.getString("device"));
//                                    object.put("scsiId", mounts.getString("uuid"));
//                                    resultList.add(object);
//                                }

                                //废弃，重新以json方式处理结果数据
                                //以String分行读取的方式进行取数据
                                String messageObj = resultObj.getString("message");
                                if (StringUtils.isNotBlank(messageObj)) {
                                    BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(messageObj.getBytes(Charset.forName("utf8"))), Charset.forName("utf8")));
                                    List<String> lines = new ArrayList<>();
                                    String line;
                                    StringBuffer strbuf = new StringBuffer();
                                    while ((line = br.readLine()) != null) {
                                        if (!line.trim().equals("")) {
                                            strbuf.append(line + "\r\n");
                                            lines.add(line);
                                        }
                                    }
                                    if (ListTool.isEmpty(lines)) {
                                        result = new BocloudResult<>(false, "LVM操作失败！获取worker执行结果为空，执行操作为：" + operation.name());
                                    } else {
                                        for (String stdout : lines) {
                                            if (stdout.contains("dvd")) {
                                                continue;
                                            }
                                            String[] split = stdout.split(" ");
                                            if (split.length < 2) {
                                                result = new BocloudResult<>(false, "LVM操作失败！执行操作为：" + operation.name());
                                            } else {
                                                JSONObject object = new JSONObject();
                                                String scsiId = split[split.length - 1];
                                                if (scsiId.length() <= 1) {
                                                    continue;
                                                }
                                                scsiId = scsiId.substring(scsiId.length() - 32);
                                                object.put("scsiId", scsiId);
                                                String device = "";
                                                for (String d : split) {
                                                    if (d.contains("/")) {
                                                        device = d;
                                                        break;
                                                    }
                                                }
                                                object.put("device", device);
                                                resultList.add(object);
                                            }
                                        }
                                        logger.info("lvm结果：{}", JSONObject.toJSON(resultList));
                                        result = new BocloudResult<>(true, resultList, "LVM操作成功！执行操作为：" + operation.name());
                                    }
                                } else {
                                    result = new BocloudResult<>(false, "LVM操作失败！获取worker执行结果为空，执行操作为：" + operation.name());
                                }
                            } else {
                                result = new BocloudResult<>(false, "LVM操作失败！获取worker执行结果为空，执行操作为：" + operation.name());
                            }
                        } else {
                            result = new BocloudResult<>(true, "LVM扩容成功！");
                        }
                    } else {
                        String data = jsonObject.getString("data");
                        String msg = "LVM执行失败！获取worker执行结果为空，执行操作为：" + operation.name();
                        if (StringUtils.isNotBlank(data)) {
                            msg += "，错误信息为：" + data;
                        }
                        result = new BocloudResult<>(false, msg);
                    }
                } else {
                    logger.error("获取任务执行结果消息超时！执行操作为：" + operation.name());
                    result = new BocloudResult<>(false, "执行失败！获取worker执行结果为空，执行操作为：" + operation.name());
                }
            } catch (Exception e) {

                logger.error("执行操作为：" + operation.name() + "，等待worker返回任务结果消息异常:", e);
                result = new BocloudResult<>(false, "执行操作为：" + operation.name() + "，执行失败！" + bocloudResult.getMessage());
            } finally {
                amqpAdmin.deleteQueue(resultQueue);
            }
        } else {
            logger.error("请求发送到worker失败：{}", bocloudResult.getMessage());
            result = new BocloudResult<>(false, "执行操作为：" + operation.name() + "执行失败！" + bocloudResult.getMessage());
        }
        return result;

    }

    /**
     * 处理请求结果
     *
     * @param vendor
     * @param id
     * @param result
     * @param context
     */
    public void handleResult(CloudVendor vendor, Long id, BocloudResult result, RequestContext context) {
        String operate = vendor.getType().toLowerCase() + ".vm";
        String content = "云主机创建LVM成功";
        if (result.isFailed()) {
            content = "云主机创建LVM失败：" + result.getMessage();
        }
        sendMsg(result.isSuccess(), operate, content, vendor, id, context);
    }

    /**
     * 发送执行结果给用户
     *
     * @param success
     * @param operate
     * @param content
     * @param vendor
     * @param id
     * @param context
     */
    private void sendMsg(boolean success, String operate, String content, CloudVendor vendor, Long id,
                         RequestContext context) {
        resourceEventPublisher.send(new OperateResult(success, content, operate,
                MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
        NotifyMessage message = new NotifyMessage(context, "云主机创建LVM", content, true, false);
        amqpTemplate.convertAndSend(BoCloudExchange.Default.DIRECT.getExchange(), "event.notice.queue", message);
    }
}
