package com.bocloud.ims.service.resource;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.loadbalance.LbDriver;
import com.bocloud.cmp.driver.network.ListenerDriver;
import com.bocloud.cmp.entity.enums.CloudProvider;
import com.bocloud.cmp.model.*;
import com.bocloud.common.enums.BoCloudExchange;
import com.bocloud.common.model.*;
import com.bocloud.common.model.OperateResult.OperateCategory;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.common.utils.ListTool;
import com.bocloud.common.utils.MapTools;
import com.bocloud.ims.entity.resource.LBAddBean;
import com.bocloud.ims.entity.resource.*;
import com.bocloud.ims.interfaces.resource.LbListenerService;
import com.bocloud.ims.repository.resource.*;
import com.bocloud.ims.service.utils.ResourceEventPublisher;
import com.bocloud.service.lock.BocloudACLock;
import com.bocloud.service.lock.LockFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 负载均衡器监听器service实现
 *
 * @author wangyu
 * @version 1.0
 * @since 2017年9月4日
 */
@Service("lbListenerService")
public class LbListenerServiceImpl implements LbListenerService {

    private static Logger logger = LoggerFactory.getLogger(LbListenerServiceImpl.class);
    private static OperateCategory operateCategory = OperateResult.OperateCategory.ResourceEvent;
    @Autowired
    private LoadBalancerRepository loadBalancerRepository;
    @Autowired
    private LbListenerRepository lbListenerRepository;
    @Autowired
    private CloudVendorRepository cloudVendorRepository;
    @Autowired
    private LbMemberRepository lbMemberRepository;
    @Autowired
    private LbPoolRepository lbPoolRepository;
    @Autowired
    private HealthMonitorRepository healthMonitorRepository;
    @Autowired
    private LbDriver lbDriver;
    @Autowired
    private ListenerDriver listenerDriver;
    @Autowired
    private ResourceEventPublisher resourceEventPublisher;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private LockFactory lockFactory;
    @Autowired
    private LbTargetGroupRepository lbTargetGroupRepository;
    @Autowired
    private AccessControlRepository accessControlRepository;
    @Autowired
    private LbListenerRuleRepository lbListenerRuleRepository;

    @Override
    public BocloudResult<GridBean<LbListener>> list(Pager pager, RequestContext context) {
        GridBean gridBean = null;
        try {
            List<Param> params = Optional.ofNullable(pager.getParams()).orElse(new ArrayList<>());
            Map<String, String> sorter = Optional.ofNullable(pager.getSorter()).orElse(Maps.newHashMap());
            Boolean simple = Optional.ofNullable(pager.getSimple()).orElse(false);
            Integer page = Optional.ofNullable(pager.getPage()).orElse(1);
            Integer rows = Optional.ofNullable(pager.getRows()).orElse(10);
            sorter.put("gmtCreate", Common.ONE);
            int total = lbListenerRepository.count(params);
            if (simple) {
                if (0 == context.getTenant()) {
                    params.add(new Param(MapTools.simpleMap(Common.TENANTID, 0), Sign.EQ));
                }
                List<SimpleBean> beans = lbListenerRepository.list(params, sorter);
                gridBean = new GridBean(1, 1, total, beans);
            } else {
                List<LbListener> list = lbListenerRepository.list(page, rows, params, sorter);
                Map<String, LbPool> poolMap = Maps.newHashMap();
                if (!list.isEmpty()) {
                    List<LbPool> pools = lbPoolRepository.listByLbId(list.get(0).getLbId());
                    for (LbPool pool : pools) {
                        poolMap.put(pool.getPoolUuid(), pool);
                    }
                }
                for (LbListener lbListener : list) {
                    if (null != lbListener.getDefaultPoolUuid()
                            && null != poolMap.get(lbListener.getDefaultPoolUuid())) {
                        lbListener.setPoolName(poolMap.get(lbListener.getDefaultPoolUuid()).getName());
                        lbListener.setPoolId(poolMap.get(lbListener.getDefaultPoolUuid()).getId());
                    }
                    if (null != lbListener.getDefaultActions()) {
                        lbListener.setDefaultActions(JSONObject.parseArray(lbListener.getDefaultActions().toString()));
                    }
                    if (null != lbListener.getConfiguration()) {
                        if (null != lbListener.getDefaultPoolUuid()) {
                            CloudVendor vendor = cloudVendorRepository.query(lbListener.getVendorId());
                            Assert.notNull(vendor, "不存在此平台");
                            if (!CloudProvider.VOLCENGINE.name().equals(vendor.getType())) {
                                JSONObject configuration = JSONObject.parseObject(lbListener.getConfiguration().toString());
                                LbPool lbPool = lbPoolRepository.queryByUuid(lbListener.getDefaultPoolUuid(), lbListener.getVendorId());
                                configuration.put("poolId", lbPool.getId());
                                lbListener.setConfiguration(configuration.toJSONString());
                            } else {
                                List<JSONObject> array = JSONArray.parseArray(lbListener.getConfiguration().toString(), JSONObject.class);
                                for (JSONObject json : array) {
                                    LbPool lbPool = lbPoolRepository.queryByUuid(lbListener.getDefaultPoolUuid(), lbListener.getVendorId());
                                    lbListener.setPoolId(lbPool.getId());
                                    json.put("poolId", lbPool.getId());
                                }
                                lbListener.setConfiguration(JSONObject.toJSONString(array));
                            }
                        }
                    }
                }
                gridBean = GridHelper.getBean(page, rows, total, list);
            }
            return new BocloudResult<>(true, gridBean, "查询成功");
        } catch (Exception e) {
            logger.error("list lb listener failure:", e);
            return new BocloudResult<>(false, "查询失败");
        }
    }

    @Override
    public BocloudResult create(LBAddBean bean, RequestContext context, String callback) {
        BocloudResult result = new BocloudResult(false, "负载均衡器创建失败");
        try {
            LbListener listener = bean.getListener();
            LoadBalancer balancer = loadBalancerRepository.query(listener.getLbId());
            if (null == balancer) {
                return new BocloudResult(false, "负载均衡器不存在");
            }
            Long vendorId = balancer.getVendorId();
            CloudVendor vendor = cloudVendorRepository.query(vendorId);
            if (null == vendor) {
                return new BocloudResult(false, "云平台不存在");
            }
            switch (CloudProvider.valueOf(vendor.getType())) {
                case AWS:
                    result = createAWS(bean, context, callback);
                    break;
                case ALIYUN:
                    result = createALIYUN(bean, context, callback);
                    break;
                case HUAWEI:
                case HCSO:
                    result = createHUAWEI(bean, context, callback);
                    break;
                case VOLCENGINE:
                    result = createVOLCENGINE(bean, context, callback);
                    break;
                default:
                    result = createNormal(bean, context, callback);
                    break;
            }
        } catch (Exception e) {
            logger.error("create load balancer fail:", e);
        }
        return result;
    }

    private BocloudResult createVOLCENGINE(LBAddBean bean, RequestContext context, String callback) {
        try {
            LbListener listener = bean.getListener();
            if (null == listener) {
                return new BocloudResult(false, "参数设置有误");
            }

            Long lbId = listener.getLbId();
            LoadBalancer balancer = loadBalancerRepository.query(lbId);
            if (null == balancer) {
                return new BocloudResult(false, "负载均衡器不存在");
            }
            listener.setLbUuid(balancer.getLbUuid());
            Long vendorId = balancer.getVendorId();
            CloudVendor vendor = cloudVendorRepository.query(vendorId);
            if (null == vendor) {
                return new BocloudResult(false, "云平台不存在");
            }

            boolean flag = lbListenerRepository.portAndProtocolExist(listener.getPort(), listener.getProtocol(), lbId);
            if (flag) {
                return new BocloudResult(false, "负载均衡器下已有相同端口号的监听器");
            }

            Long poolId = listener.getPoolId();
            if (null == poolId && poolId == 0) {
                return new BocloudResult(false, "参数设置有误");
            }
            LbPool lbPool = lbPoolRepository.query(poolId);
            if (null == lbPool) {
                return new BocloudResult(false, "后端服务器组不存在");
            }
            listener.setDefaultPoolUuid(lbPool.getPoolUuid());
            LbPool oldLbPool = lbPool;
            /* 启动一个线程从MQ上获取数据 */

            new Thread(new Runnable() {
                @Override
                public void run() {
                    String operate = vendor.getType().toLowerCase() + ".listener";
                    String lisName = StringUtils.isEmpty(listener.getName()) ? "auto_named_listener" : listener.getName();
                    String content = "监听器【" + lisName + "】创建失败";
                    boolean success = true;
                    try {
                        LbListenerModel listenerModel = new LbListenerModel();
                        BeanUtils.copyProperties(listener, listenerModel);
                        listenerModel.setLbUuid(balancer.getLbUuid());
                        String path = LoadBalancer.class.getSimpleName() + "_" + lbId;
                        BocloudResult result = null;
                        try (BocloudACLock lock = lockFactory.getACLock(path)) {
                            Assert.isTrue(lock.acquire(600, TimeUnit.SECONDS), "请求超时");
                            result = lbDriver.createListener(vendor.getUuid(), balancer.getRegion(), listenerModel);
                            if (result.isFailed()) {
                                NotifyMessage message = new NotifyMessage(context, "监听器创建", content, true, false);
                                amqpTemplate.convertAndSend(BoCloudExchange.Default.DIRECT.getExchange(),
                                        "event.notice.queue", message);
                                resourceEventPublisher.send(new OperateResult(false, content, operate,
                                        MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));

                                success = false;
                            } else {
                                Long userId = context.getTarget();
                                // 创建监听器
                                listenerModel = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
                                        LbListenerModel.class);
                                BeanUtils.copyProperties(listenerModel, listener);
                                Object configuration = listenerModel.getConfiguration();
                                if (null != configuration) {
                                    listener.setConfiguration(JSONObject.toJSONString(configuration));
                                }
                                Object certificates = listenerModel.getCertificates();
                                if (null != certificates) {
                                    listener.setCertificates(JSONObject.toJSONString(certificates));
                                }
                                listener.setCreatorId(userId);
                                listener.setMenderId(userId);
                                listener.setLbUuid(balancer.getLbUuid());
                                listener.setLbId(balancer.getId());
                                listener.setVendorId(vendorId);
                                listener.setRegionId(balancer.getRegion());
                                lbListenerRepository.save(listener);
                                List<LbListenerRuleModel> listenerRuleModels = listenerModel.getListenerRuleModels();
                                if (!ListTool.isEmpty(listenerRuleModels)) {
                                    for (LbListenerRuleModel model : listenerRuleModels) {
                                        LbListenerRule lbListenerRule = new LbListenerRule();
                                        BeanUtils.copyProperties(model, lbListenerRule);
                                        lbListenerRule.setVendorId(vendorId);
                                        lbListenerRule.setRegionId(balancer.getRegion());
                                        lbListenerRule.setCreatorId(userId);
                                        lbListenerRule.setGmtCreate(new Date());
                                        lbListenerRuleRepository.save(lbListenerRule);
                                    }
                                }
                                content = "监听器【" + listener.getName() + "】创建成功";
                                resourceEventPublisher.send(new OperateResult(true, content, operate,
                                        MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                            }
                        } catch (Exception e) {
                            logger.error("Get error message：", e);
                            result = new BocloudResult(false, "获取创建监听器的锁异常");
                        }
                    } catch (Exception e) {
                        logger.error("Get Message Exception:", e);
                        resourceEventPublisher.send(new OperateResult(false, content, operate,
                                MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                        success = false;
                    }
                }
            }).start();
            return new BocloudResult(true, "创建任务已经下发，正在执行……");
        } catch (Exception e) {
            logger.error("create load balancer fail:", e);
            return new BocloudResult(false, "创建失败");
        }
    }

    public BocloudResult createAWS(LBAddBean bean, RequestContext context, String callback) {
        try {
            LbListener listener = bean.getListener();
            JSONArray defaultActions = (JSONArray) listener.getDefaultActions();
            if (null == listener || (defaultActions == null || defaultActions.isEmpty())) {
                return new BocloudResult(false, "参数设置有误");
            }
            Long lbId = listener.getLbId();
            LoadBalancer balancer = loadBalancerRepository.query(lbId);
            if (null == balancer) {
                return new BocloudResult(false, "负载均衡器不存在");
            }

            for (Object object : defaultActions) {
                JSONObject jsonObject = ((JSONObject) object);
                Long tgId = jsonObject.getLong("tgId");
                LbTargetGroup targetGroup = lbTargetGroupRepository.query(tgId);
                if (null == targetGroup) {
                    return new BocloudResult(false, "目标群组不存在");
                }
                jsonObject.put("targetGroupArn", targetGroup.getUuid());
            }

            Long vendorId = balancer.getVendorId();
            CloudVendor vendor = cloudVendorRepository.query(vendorId);
            if (null == vendor) {
                return new BocloudResult(false, "云平台不存在");
            }
            /* 启动一个线程从MQ上获取数据 */
            new Thread(new Runnable() {
                @Override
                public void run() {
                    String operate = vendor.getType().toLowerCase() + ".listener";
                    String content = "监听器创建失败";
                    boolean success = true;
                    try {
                        LbListenerModel listenerModel = new LbListenerModel();
                        BeanUtils.copyProperties(listener, listenerModel);
                        listenerModel.setLbUuid(balancer.getLbUuid());
                        listenerModel.setDefaultActions(defaultActions);
                        String path = LoadBalancer.class.getSimpleName() + "_" + lbId;
                        BocloudResult result = null;
                        try (BocloudACLock lock = lockFactory.getACLock(path)) {
                            Assert.isTrue(lock.acquire(600, TimeUnit.SECONDS), "请求超时");
                            result = listenerDriver.create(listenerModel, vendor.getUuid(), balancer.getRegion());
                        } catch (Exception e) {
                            logger.error("Get error message：", e);
                            result = new BocloudResult(false, "获取创建监听器的锁异常");
                        }
                        if (result.isFailed()) {
                            resourceEventPublisher.send(new OperateResult(false, content, operate,
                                    MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                            success = false;
                        } else {
                            // 创建监听器
                            listenerModel = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
                                    LbListenerModel.class);
                            BeanUtils.copyProperties(listenerModel, listener);
                            listener.setLbUuid(balancer.getLbUuid());
                            listener.setLbId(balancer.getId());
                            listener.setCertificates(listenerModel.getCertificates() != null
                                    ? listenerModel.getCertificates().toJSONString()
                                    : null);
                            listener.setAlpnPolicy(
                                    listenerModel.getAlpnPolicy() != null ? listenerModel.getAlpnPolicy().toJSONString()
                                            : null);
                            listener.setDefaultActions(listenerModel.getDefaultActions().toJSONString());
                            listener.setVendorId(vendorId);
                            listener.setRegionId(balancer.getRegion());
                            lbListenerRepository.save(listener);
                            content = "监听器创建成功";
                            resourceEventPublisher.send(new OperateResult(true, content, operate,
                                    MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                        }
                    } catch (Exception e) {
                        logger.error("Get Message Exception:", e);
                        resourceEventPublisher.send(new OperateResult(false, content, operate,
                                MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                        success = false;
                    }
                }
            }).start();
            return new BocloudResult(true, "创建任务已经下发，正在执行……");
        } catch (Exception e) {
            logger.error("create load balancer fail:", e);
            return new BocloudResult(false, "创建失败");
        }
    }

    private BocloudResult createHUAWEI(LBAddBean bean, RequestContext context, String callback) {
        try {
            LbListener listener = bean.getListener();
            if (null == listener) {
                return new BocloudResult(false, "参数设置有误");
            }

            Long lbId = listener.getLbId();
            LoadBalancer balancer = loadBalancerRepository.query(lbId);
            if (null == balancer) {
                return new BocloudResult(false, "负载均衡器不存在");
            }
            Long vendorId = balancer.getVendorId();
            CloudVendor vendor = cloudVendorRepository.query(vendorId);
            if (null == vendor) {
                return new BocloudResult(false, "云平台不存在");
            }

            boolean flag = lbListenerRepository.portExist(listener.getPort(), lbId);
            if (flag) {
                return new BocloudResult(false, "负载均衡器下已有相同端口号的监听器");
            }

            LbPool pool = listener.getPool();

            Long poolId = listener.getPoolId();
            LbPool lbPool = null;
            if (null != poolId && poolId != 0) {
                lbPool = lbPoolRepository.query(poolId);
                if (null == lbPool) {
                    return new BocloudResult(false, "后端服务器组不存在");
                }
                if (!listener.getProtocol().equalsIgnoreCase(lbPool.getProtocol())) {
                    return new BocloudResult(false, "监听器与后端服务器组协议不一致");
                }
                listener.setDefaultPoolUuid(lbPool.getPoolUuid());
            } else if (null == pool) {
                return new BocloudResult(false, "参数设置有误");
            } else {
                if (!listener.getProtocol().equalsIgnoreCase(pool.getProtocol())) {
                    return new BocloudResult(false, "监听器与后端服务器组协议不一致");
                }
            }

            LbPool oldLbPool = lbPool;
            if (StringUtils.isEmpty(listener.getRemark())) {
                listener.setRemark(pool.getRemark());
            }
            /* 启动一个线程从MQ上获取数据 */

            new Thread(new Runnable() {
                @Override
                public void run() {
                    String operate = vendor.getType().toLowerCase() + ".listener";
                    String lisName = StringUtils.isEmpty(listener.getName()) ? "auto_named_listener" : listener.getName();
                    String content = "监听器【" + lisName + "】创建失败";
                    boolean success = true;
                    try {
                        LbListenerModel listenerModel = new LbListenerModel();
                        BeanUtils.copyProperties(listener, listenerModel);
                        listenerModel.setLbUuid(balancer.getLbUuid());
                        String path = LoadBalancer.class.getSimpleName() + "_" + lbId;
                        BocloudResult result = null;
                        try (BocloudACLock lock = lockFactory.getACLock(path)) {
                            Assert.isTrue(lock.acquire(600, TimeUnit.SECONDS), "请求超时");
                            if (null != pool) {
                                // 创建服务器组
                                LbPoolModel poolModel = new LbPoolModel();
                                BeanUtils.copyProperties(pool, poolModel);
                                if (StringUtils.isEmpty(poolModel.getName())) {
                                    poolModel.setName(listener.getName() + "_pool");
                                }
                                poolModel.setLbUuid(balancer.getLbUuid());

                                result = lbDriver.createPool(vendor.getUuid(), balancer.getRegion(), poolModel);

                                if (result.isFailed()) {
                                    NotifyMessage message = new NotifyMessage(context, "监听器创建", content, true, false);
                                    amqpTemplate.convertAndSend(BoCloudExchange.Default.DIRECT.getExchange(),
                                            "event.notice.queue", message);
                                    resourceEventPublisher.send(new OperateResult(false, content, operate,
                                            MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                                    return;
                                }
                                // 创建后端服务器组
                                poolModel = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
                                        LbPoolModel.class);
                                BeanUtils.copyProperties(poolModel, pool);

                                HealthMonitor healthMonitor = pool.getMonitor();
                                if (null != healthMonitor) {
                                    // 创建健康检查
                                    HealthMonitorModel hmModel = new HealthMonitorModel();
                                    BeanUtils.copyProperties(healthMonitor, hmModel);

                                    hmModel.setPoolUuid(pool.getPoolUuid());

                                    BocloudResult bocloudResult = lbDriver.createHealMonitor(vendor.getUuid(),
                                            balancer.getRegion(), hmModel);
                                    if (bocloudResult.isFailed()) {
                                        NotifyMessage message = new NotifyMessage(context, "监听器创建", content, true,
                                                false);
                                        amqpTemplate.convertAndSend(BoCloudExchange.Default.DIRECT.getExchange(),
                                                "event.notice.queue", message);
                                        resourceEventPublisher.send(new OperateResult(false, content, operate,
                                                MapTools.simpleMap("vendorId", vendor.getId()), operateCategory,
                                                context));
                                        // todo 删除后端服务器组
                                        lbDriver.removePool(vendor.getUuid(), pool.getRegionId(), pool.getPoolUuid());
                                        return;
                                    }
                                    hmModel = JSONObject.parseObject(JSONObject.toJSONString(bocloudResult.getData()),
                                            HealthMonitorModel.class);
                                    BeanUtils.copyProperties(hmModel, healthMonitor);
                                    pool.setMonitor(healthMonitor);

                                }

                                // 监听对应的默认后端服务器组
                                listenerModel.setDefaultPoolUuid(pool.getPoolUuid());
                            }

                            result = lbDriver.createListener(vendor.getUuid(), balancer.getRegion(), listenerModel);

                            if (result.isFailed()) {
                                NotifyMessage message = new NotifyMessage(context, "监听器创建", content, true, false);
                                amqpTemplate.convertAndSend(BoCloudExchange.Default.DIRECT.getExchange(),
                                        "event.notice.queue", message);
                                resourceEventPublisher.send(new OperateResult(false, content, operate,
                                        MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));

                                success = false;
                            } else {

                                Long userId = context.getTarget();
                                // 创建监听器
                                listenerModel = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
                                        LbListenerModel.class);
                                BeanUtils.copyProperties(listenerModel, listener);
                                listener.setCreatorId(userId);
                                listener.setMenderId(userId);
                                listener.setLbUuid(balancer.getLbUuid());
                                listener.setLbId(balancer.getId());
                                listener.setVendorId(vendorId);
                                listener.setRegionId(balancer.getRegion());
                                listener.setCertificates(listenerModel);
                                lbListenerRepository.save(listener);

                                if (null != pool) {
                                    pool.setCreatorId(userId);
                                    pool.setMenderId(userId);
                                    pool.setVendorId(vendorId);
                                    pool.setRegionId(balancer.getRegion());
                                    pool.setListenerUuid(listener.getListenerUuid());
                                    pool.setListenerId(listener.getId());
                                    pool.setLbUuid(balancer.getLbUuid());
                                    pool.setLbId(balancer.getId());

                                    HealthMonitor healthMonitor = pool.getMonitor();
                                    if (null != healthMonitor) {
                                        pool.setHmUuid(healthMonitor.getHealthUuid());
                                    }

                                    lbPoolRepository.save(pool);

                                    if (null != healthMonitor) {
                                        healthMonitor.setCreatorId(userId);
                                        healthMonitor.setMenderId(userId);
                                        healthMonitor.setVendorId(vendorId);
                                        healthMonitor.setRegionId(balancer.getRegion());
                                        healthMonitor.setListenerId(listener.getId());
                                        healthMonitor.setPoolId(pool.getId());
                                        healthMonitorRepository.save(healthMonitor);
                                    }
                                }

                                if (null != oldLbPool) {
                                    oldLbPool.setListenerUuid(listener.getListenerUuid());
                                    oldLbPool.setListenerId(listener.getId());
                                    oldLbPool.setMenderId(context.getTarget());
                                    lbPoolRepository.update(oldLbPool);
                                    lbMemberRepository.updateByPoolId(oldLbPool.getId(), context.getTarget(),
                                            listener.getId());
                                }

                                content = "监听器【" + listener.getName() + "】创建成功";
                                resourceEventPublisher.send(new OperateResult(true, content, operate,
                                        MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                            }
                        } catch (Exception e) {
                            logger.error("Get error message：", e);
                            result = new BocloudResult(false, "获取创建监听器的锁异常");
                        }
                    } catch (Exception e) {
                        logger.error("Get Message Exception:", e);
                        resourceEventPublisher.send(new OperateResult(false, content, operate,
                                MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                        success = false;
                    }
                }
            }).start();
            return new BocloudResult(true, "创建任务已经下发，正在执行……");
        } catch (Exception e) {
            logger.error("create load balancer fail:", e);
            return new BocloudResult(false, "创建失败");
        }

    }

    private BocloudResult createALIYUN(LBAddBean bean, RequestContext context, String callback) {
        try {
            LbListener listener = bean.getListener();
            Long lbId = listener.getLbId();
            LoadBalancer balancer = loadBalancerRepository.query(lbId);
            if (null == balancer) {
                return new BocloudResult(false, "负载均衡器不存在");
            }
            final LbListenerModel[] listenerModel = {
                    JSONObject.parseObject(listener.getConfiguration().toString(), LbListenerModel.class)};
            if (null == listenerModel[0]) {
                return new BocloudResult(false, "监听器业务配置数据不存在");
            }
            LbPool lbPool = lbPoolRepository.query(listenerModel[0].getPoolId());
            if (null == lbPool) {
                return new BocloudResult(false, "资源池数据不存在");
            }
            listenerModel[0].setDefaultPoolUuid(lbPool.getPoolUuid());
            Long vendorId = balancer.getVendorId();
            CloudVendor vendor = cloudVendorRepository.query(vendorId);
            if (null == vendor) {
                return new BocloudResult(false, "云平台不存在");
            }
            String aclId = listenerModel[0].getAclId();
            if (null != aclId) {
                AccessControl accessControl = accessControlRepository.query(Long.valueOf(aclId));
                listenerModel[0].setAclId(accessControl.getAclUuId());
            }
            /* 启动一个线程从MQ上获取数据 */
            new Thread(new Runnable() {
                @Override
                public void run() {
                    String operate = vendor.getType().toLowerCase() + ".listener";
                    String content = "监听器创建失败";
                    boolean success = true;
                    try {
                        listenerModel[0].setLbUuid(balancer.getLbUuid());
                        if (null == listenerModel[0].getBandwidth()) {
                            listenerModel[0].setBandwidth(-1);
                        }
                        listenerModel[0].setProtocol(listenerModel[0].getProtocol().toUpperCase());
                        String path = LoadBalancer.class.getSimpleName() + "_" + lbId;
                        BocloudResult result = null;
                        try (BocloudACLock lock = lockFactory.getACLock(path)) {
                            Assert.isTrue(lock.acquire(600, TimeUnit.SECONDS), "请求超时");
                            result = lbDriver.createListener(vendor.getUuid(), balancer.getRegion(), listenerModel[0]);
                        } catch (Exception e) {
                            logger.error("Get error message：", e);
                            result = new BocloudResult(false, "获取创建监听器的锁异常");
                        }
                        if (result.isFailed()) {
                            resourceEventPublisher.send(new OperateResult(false, result.getMessage(), operate,
                                    MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                            success = false;
                        } else {
                            // 创建监听器
                            listenerModel[0] = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
                                    LbListenerModel.class);
                            if(null != listenerModel[0].getPersistenceTimeout()){
                                listenerModel[0].setStickySession(listenerModel[0].getPersistenceTimeout() > 0);
                            }
                            BeanUtils.copyProperties(listenerModel[0], listener);
                            listener.setLbUuid(balancer.getLbUuid());
                            listener.setLbId(balancer.getId());
                            listener.setVendorId(vendorId);
                            listener.setRegionId(balancer.getRegion());
                            listener.setCertificates(JSONObject.parseObject(JSONObject.toJSONString(listenerModel[0])));
                            lbListenerRepository.save(listener);
                            content = "监听器创建成功";
                            resourceEventPublisher.send(new OperateResult(true, content, operate,
                                    MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                        }
                    } catch (Exception e) {
                        logger.error("Get Message Exception:", e);
                        resourceEventPublisher.send(new OperateResult(false, content, operate,
                                MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                        success = false;
                    }
                }
            }).start();
            return new BocloudResult(true, "创建任务已经下发，正在执行……");
        } catch (Exception e) {
            logger.error("create load balancer fail:", e);
            return new BocloudResult(false, "创建失败");
        }

    }

    public BocloudResult createNormal(LBAddBean bean, RequestContext context, String callback) {
        try {
            Long userId = context.getTarget();
            Long tenantId = context.getTenant();
            Long projectId = context.getProject();
            LbListener listener = bean.getListener();
            LbPool pool = bean.getPool();
            HealthMonitor monitor = bean.getMonitor();
            if (null == listener || null == pool || null == monitor) {
                return new BocloudResult(false, "参数设置有误");
            }
            Long lbId = listener.getLbId();
            LoadBalancer balancer = loadBalancerRepository.query(lbId);
            if (null == balancer) {
                return new BocloudResult(false, "负载均衡器不存在");
            }
            Long vendorId = balancer.getVendorId();
            CloudVendor vendor = cloudVendorRepository.query(vendorId);
            if (null == vendor) {
                return new BocloudResult(false, "云平台不存在");
            }
            boolean flag = lbListenerRepository.portExist(listener.getPort(), listener.getProtocol(), lbId);
            if (flag) {
                return new BocloudResult(false, "该监听器端口已存在");
            }
            // 启动一个线程从MQ上获取数据
            new Thread(new Runnable() {
                @Override
                public void run() {
                    String operate = vendor.getType().toLowerCase() + ".listener";
                    String content = "监听器【" + listener.getName() + "】创建失败";
                    boolean success = true;
                    try {
                        LbListenerModel listenerModel = new LbListenerModel();
                        BeanUtils.copyProperties(listener, listenerModel);
                        LbPoolModel poolModel = new LbPoolModel();
                        BeanUtils.copyProperties(pool, poolModel);
                        poolModel.setName(listener.getName() + "_pool");
                        HealthMonitorModel monitorModel = new HealthMonitorModel();
                        BeanUtils.copyProperties(monitor, monitorModel);
                        List<LbMember> members = bean.getMembers();
                        List<LbMemberModel> memberModels = Lists.newArrayList();
                        Map<String, Long> subnetMap = Maps.newHashMap();
                        if (!ListTool.isEmpty(members)) {
                            for (LbMember member : members) {
                                LbMemberModel memberModel = new LbMemberModel();
                                BeanUtils.copyProperties(member, memberModel);
                                memberModels.add(memberModel);
                                subnetMap.put(member.getSubnetUuid(), member.getSubnetId());
                            }
                        }
                        poolModel.setModel(monitorModel);
                        listenerModel.setPoolModel(poolModel);
                        listenerModel.setModels(memberModels);
                        listenerModel.setLbUuid(balancer.getLbUuid());
                        String path = LoadBalancer.class.getSimpleName() + "_" + lbId;
                        BocloudResult result = null;
                        try (BocloudACLock lock = lockFactory.getACLock(path)) {
                            Assert.isTrue(lock.acquire(600, TimeUnit.SECONDS), "请求超时");
                            result = lbDriver.createListener(vendor.getUuid(), null, listenerModel);
                        } catch (Exception e) {
                            logger.error("Get error message：", e);
                            result = new BocloudResult(false, "获取创建监听器的锁异常");
                        }
                        if (result.isFailed()) {
                            resourceEventPublisher.send(new OperateResult(false, content, operate,
                                    MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                            success = false;
                        } else {
                            // 创建监听器
                            listenerModel = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
                                    LbListenerModel.class);
                            BeanUtils.copyProperties(listenerModel, listener);
                            listener.setLbUuid(balancer.getLbUuid());
                            listener.preSave(userId, userId, vendorId, lbId, tenantId, projectId);
                            lbListenerRepository.save(listener);
                            // 创建pool池
                            poolModel = listenerModel.getPoolModel();
                            BeanUtils.copyProperties(poolModel, pool);
                            pool.setListenerUuid(listener.getListenerUuid());
                            pool.preSave(userId, userId, vendorId, listener.getId(), tenantId, projectId);
                            lbPoolRepository.save(pool);
                            // 创建健康检查
                            monitorModel = poolModel.getModel();
                            BeanUtils.copyProperties(monitorModel, monitor);
                            monitor.setPoolUuid(pool.getPoolUuid());
                            monitor.preSave(userId, userId, vendorId, listener.getId(), pool.getId(), tenantId,
                                    projectId);
                            healthMonitorRepository.save(monitor);
                            // 创建成员
                            List<LbMemberModel> models = listenerModel.getModels();
                            if (!ListTool.isEmpty(models)) {
                                for (LbMemberModel model : models) {
                                    LbMember member = new LbMember();
                                    BeanUtils.copyProperties(model, member);
                                    member.setName(model.getAddress());
                                    member.preSave(userId, userId, vendorId, listener.getId(), pool.getId(),
                                            subnetMap.get(member.getSubnetUuid()), tenantId, projectId);
                                    lbMemberRepository.save(member);
                                }
                            }
                            content = "监听器【" + listener.getName() + "】创建成功";
                            resourceEventPublisher.send(new OperateResult(true, content, operate,
                                    MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                        }
                    } catch (Exception e) {
                        logger.error("Get Message Exception:", e);
                        resourceEventPublisher.send(new OperateResult(false, content, operate,
                                MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                        success = false;
                    }
                    if (!StringUtils.isEmpty(callback)) {
                        BocloudResult bocloudResult = new BocloudResult(success, content);
                        if (success) {
                            listener.setPoolId(pool.getId());
                            bocloudResult.setData(listener);
                        }
                        amqpTemplate.convertAndSend(callback, JSONObject.toJSON(bocloudResult));
                    }
                }
            }).start();
            return new BocloudResult(true, "创建任务已经下发，正在执行……");
        } catch (Exception e) {
            logger.error("create load balancer fail:", e);
            return new BocloudResult(false, "创建失败");
        }
    }

    @Override
    public BocloudResult modify(LbListener listener, Long userId) {
        String path = LbListener.class.getSimpleName() + "_" + listener.getId();
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            LbListener lbListener = lbListenerRepository.query(listener.getId());
            if (null == lbListener) {
                return new BocloudResult<>(false, "数据不存在");
            }
            CloudVendor vendor = cloudVendorRepository.query(lbListener.getVendorId());
            if (null == vendor) {
                return new BocloudResult<>(false, "云平台不存在");
            }
            LbListenerModel model = new LbListenerModel();
            BocloudResult result = null;
            JSONObject configurationObject = JSON.parseObject(JSON.toJSONString(listener.getConfiguration()));
            LbPool pool = lbPoolRepository.query(Long.valueOf(configurationObject.get("poolId").toString()));
            if (null != pool) {
                listener.setDefaultPoolUuid(pool.getPoolUuid());
            }
            switch (CloudProvider.valueOf(vendor.getType())) {
                case ALIYUN:
                    if(configurationObject.get("scheduler").equals("ch")){
                        return new BocloudResult<>(false, "调度算法为一致性哈希的数据不支持修改");
                    }
                    model.setLbUuid(lbListener.getLbUuid());
                    model.setDefaultPoolUuid(listener.getDefaultPoolUuid());
                    model.setName(configurationObject.getString("name"));
                    model.setProtocol(configurationObject.getString("protocol"));
                    model.setPort(configurationObject.getInteger("port"));
                    model.setBandwidth(configurationObject.getInteger("bandwidth"));
                    model.setScheduler(configurationObject.getString("scheduler"));
                    model.setPersistenceTimeout(configurationObject.getInteger("persistenceTimeout"));
                    model.setConnLimit(configurationObject.getInteger("connLimit"));
                    model.setHealthyThreshold(configurationObject.getInteger("healthyThreshold"));
                    model.setUnhealthyThreshold(configurationObject.getInteger("unhealthyThreshold"));
                    model.setXForwardedFor(configurationObject.getBoolean("xForwardedFor"));
                    model.setHealthCheck(configurationObject.getBoolean("healthCheck"));
                    model.setHealthCheckConnectPort(configurationObject.getInteger("healthCheckConnectPort"));
                    model.setHealthCheckHttpCode(configurationObject.getString("healthCheckHttpCode"));
                    model.setHealthCheckConnectTimeout(configurationObject.getInteger("healthCheckConnectTimeout"));
                    model.setHealthCheckInterval(configurationObject.getInteger("healthCheckInterval"));

                    model.setAclStatus(configurationObject.getBoolean("aclStatus") == null ? false
                            : configurationObject.getBoolean("aclStatus"));
                    model.setStickySession(configurationObject.getBoolean("stickySession") == null ? false
                            : configurationObject.getBoolean("stickySession"));
                    model.setGzip(configurationObject.getBoolean("gzip") == null ? false
                            : configurationObject.getBoolean("gzip"));
                    model.setXForwardedFor(configurationObject.getBoolean("xForwardedFor") == null ? false
                            : configurationObject.getBoolean("xForwardedFor"));
                    model.setXForwardedFor_SLBID(configurationObject.getBoolean("xForwardedFor_SLBID") == null ? false
                            : configurationObject.getBoolean("xForwardedFor_SLBID"));
                    model.setXForwardedFor_SLBID(configurationObject.getBoolean("xForwardedFor_SLBID") == null ? false
                            : configurationObject.getBoolean("xForwardedFor_SLBID"));
                    model.setXForwardedFor_SLBIP(configurationObject.getBoolean("xForwardedFor_SLBIP") == null ? false
                            : configurationObject.getBoolean("xForwardedFor_SLBIP"));
                    model.setXForwardedFor_proto(configurationObject.getBoolean("xForwardedFor_proto") == null ? false
                            : configurationObject.getBoolean("xForwardedFor_proto"));
                    model.setXForwardedFor(configurationObject.getBoolean("xForwardedFor") == null ? false
                            : configurationObject.getBoolean("xForwardedFor"));
                    result = lbDriver.updateListener(vendor.getUuid(), lbListener.getRegionId(), model);
                    break;
                case HUAWEI:
                case HCSO:
                    BeanUtils.copyProperties(lbListener, model);
                    com.bocloud.ims.service.utils.BeanUtils.copyPropertiesIgnoreNull(listener, model);
                    result = lbDriver.updateListener(vendor.getUuid(), lbListener.getRegionId(), model);
                    break;
                case VOLCENGINE:
                    BeanUtils.copyProperties(listener, model);
                    model.setListenerUuid(lbListener.getListenerUuid());
                    result = lbDriver.updateListener(vendor.getUuid(), lbListener.getRegionId(), model);
                    break;
                default:
                    BeanUtils.copyProperties(listener, model);
                    result = lbDriver.updateListener(vendor.getUuid(), null, model);
                    break;
            }
            if (result.isFailed()) {
                return new BocloudResult(false, result.getMessage());
            }
            model = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), LbListenerModel.class);
            switch (CloudProvider.valueOf(vendor.getType())) {
                case HUAWEI:
                case HCSO:
                    lbListener.setName(model.getName());
                    lbListener.setRemark(model.getRemark());
                    // 监听对应的后端服务器组改变时，新老后端服务器组及后端服务器与监听关系要做变更
                    String oldPoolUuid = lbListener.getDefaultPoolUuid();
                    if (!StringUtils.equalsIgnoreCase(oldPoolUuid,model.getDefaultPoolUuid())) {
                        lbListener.setDefaultPoolUuid(model.getDefaultPoolUuid());
                        LbPool oldPool = lbPoolRepository.queryByUuid(oldPoolUuid, vendor.getId());
                        if (null != oldPool) {
                            oldPool.setListenerId(null);
                            oldPool.setListenerUuid(null);
                            oldPool.setMenderId(userId);
                            lbPoolRepository.update(oldPool);
                            lbMemberRepository.updateByPoolId(oldPool.getId(), userId, null);

                        }

                        LbPool newPool = lbPoolRepository.queryByUuid(model.getDefaultPoolUuid(), vendor.getId());
                        if (null != newPool) {
                            newPool.setListenerId(lbListener.getId());
                            newPool.setListenerUuid(lbListener.getListenerUuid());
                            newPool.setMenderId(userId);
                            lbPoolRepository.update(newPool);
                            lbMemberRepository.updateByPoolId(newPool.getId(), userId, lbListener.getId());

                        }
                    }

                    break;
                case ALIYUN:
                    //设置会话按钮状态
                    if(null!=model.getPersistenceTimeout()){
                        model.setStickySession(model.getPersistenceTimeout() > 0);
                    }
                    lbListener.setCertificates(JSONObject.parseObject(JSONObject.toJSONString(model)));
                    lbListener.setName(model.getName());
                    lbListener.setPoolId(model.getPoolId());
                    lbListener.setPoolName(pool.getName());
                    lbListener.setDefaultPoolUuid(pool.getPoolUuid());
                    break;
                case VOLCENGINE:
                    lbListener.setName(model.getName());
                    lbListener.setRemark(model.getRemark());
                    // 监听对应的后端服务器组改变时，新老后端服务器组及后端服务器与监听关系要做变更
                    if (!lbListener.getDefaultPoolUuid().equals(model.getDefaultPoolUuid())) {
                        lbListener.setDefaultPoolUuid(model.getDefaultPoolUuid());
                        LbPool oldPool = lbPoolRepository.queryByUuid(lbListener.getDefaultPoolUuid(), vendor.getId());
                        if (null != oldPool) {
                            oldPool.setListenerId(null);
                            oldPool.setListenerUuid(null);
                            oldPool.setMenderId(userId);
                            lbPoolRepository.update(oldPool);
                            lbMemberRepository.updateByPoolId(oldPool.getId(), userId, null);

                        }

                        LbPool newPool = lbPoolRepository.queryByUuid(model.getDefaultPoolUuid(), vendor.getId());
                        if (null != newPool) {
                            newPool.setListenerId(lbListener.getId());
                            newPool.setListenerUuid(lbListener.getListenerUuid());
                            newPool.setMenderId(userId);
                            lbPoolRepository.update(newPool);
                            lbMemberRepository.updateByPoolId(newPool.getId(), userId, lbListener.getId());

                        }
                    }

                    Object configuration = model.getConfiguration();
                    if (null != configuration) {
                        lbListener.setConfiguration(JSONObject.toJSONString(configuration));
                    }
                    Object certificates = model.getCertificates();
                    if (null != certificates) {
                        lbListener.setCertificates(JSONObject.toJSONString(certificates));
                    }
                    lbListener.setLbScheduler(model.getLbScheduler());
                    lbListener.setConnLimit(model.getConnLimit());
                    break;
                default:
                    BeanUtils.copyProperties(model, lbListener);
                    break;
            }
            lbListener.setMenderId(userId);
            // 更新监听器本地记录
            lbListenerRepository.update(lbListener);
            return new BocloudResult<>(true, "修改成功");
        } catch (Exception e) {
            logger.error("update lb listener fail:", e);
            return new BocloudResult<>(false, "修改失败");
        }
    }

    @Override
    public BocloudResult<LbListener> detail(Long id) {
        try {
            LbListener listener = lbListenerRepository.query(id);
            if (null == listener) {
                return new BocloudResult<>(false, "监听器不存在");
            }
            LbPool pool = lbPoolRepository.getByListenerId(id);
            if (null == pool) {
                pool = new LbPool();
            }
            listener.setPool(pool);
            listener.setPoolName(pool.getName());
            HealthMonitor monitor = healthMonitorRepository.getByPoolId(pool.getId());
            if (null == monitor) {
                monitor = new HealthMonitor();
            }
            listener.setMonitor(monitor);
            return new BocloudResult<>(true, listener, "查询成功");
        } catch (Exception e) {
            logger.error("query lb listener fail:", e);
            return new BocloudResult<>(false, "查询失败");
        }
    }

    public BocloudResult removeHUAWEI(Long id, RequestContext context, LbListener listener, CloudVendor vendor) {
        String path = LbListener.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            List<LbMember> members = lbMemberRepository.listByListenerId(id);
            if (CollectionUtils.isNotEmpty(members)) {
                return new BocloudResult(false, "当前监听器中包含后端服务器，不能执行删除操作");
            }
            BocloudResult result;
            List<LbPool> pools = lbPoolRepository.listByListenerId(listener.getId());
            if (CollectionUtils.isNotEmpty(pools)) {
                for (LbPool pool : pools) {

                    HealthMonitor healthMonitor = healthMonitorRepository.getByPoolId(pool.getId());
                    if (null != healthMonitor) {
                        // 删除健康检查
                        result = lbDriver.removeHealMonitor(vendor.getUuid(), healthMonitor.getRegionId(),
                                healthMonitor.getHealthUuid());
                        if (result.isFailed()) {
                            return new BocloudResult(false, "删除失败");
                        }
                    }
                    // 删除后端服务器组
                    result = lbDriver.removePool(vendor.getUuid(), pool.getRegionId(), pool.getPoolUuid());
                    if (result.isFailed()) {
                        return new BocloudResult(false, "删除失败");
                    }
                }
            }
            result = lbDriver.removeListener(vendor.getUuid(), listener.getRegionId(), listener.getListenerUuid());
            if (result.isFailed()) {
                return new BocloudResult(false, "删除失败: " + result.getMessage());
            }
            Long userId = context.getTarget();
            // 删除本地监听器记录
            healthMonitorRepository.removeByListenerId(id, userId);
            lbPoolRepository.removeByListenerId(id, userId);
            // lbMemberRepository.removeByListenerId(id, userId);
            lbListenerRepository.remove(id, userId);
            return new BocloudResult(true, "删除成功");
        } catch (Exception e) {
            logger.error("remove lb Listener fail:", e);
            return new BocloudResult(false, "删除失败");
        }
    }

    private BocloudResult removeALIYUN(Long id, RequestContext context, LbListener listener, CloudVendor vendor) {
        String path = LbListener.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            LoadBalancer loadBalancer = loadBalancerRepository.query(listener.getLbId());
            BocloudResult result = lbDriver.removeListener(vendor.getUuid(), listener.getRegionId(),
                    loadBalancer.getLbUuid(), listener.getProtocol(), listener.getPort());
            if (result.isFailed()) {
                return new BocloudResult(false, "删除失败");
            }
            // 删除本地监听器记录
            lbListenerRepository.remove(id, context.getTarget());
            return new BocloudResult(true, "删除成功");
        } catch (Exception e) {
            logger.error("remove lb Listener fail:", e);
            return new BocloudResult(false, "删除失败");
        }
    }

    public BocloudResult removeAWS(Long id, RequestContext context, LbListener listener, CloudVendor vendor) {
        String path = LbListener.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            List<LbListener> listeners = lbListenerRepository.listByLbId(listener.getLbId());
            if (listeners.size() == 1) {
                return new BocloudResult(false, "每个负载均衡器最少需要一个监听器");
            }
            BocloudResult result = listenerDriver.remove(listener.getListenerUuid(), vendor.getUuid(),
                    listener.getRegionId());

            if (result.isFailed()) {
                return new BocloudResult(false, "删除失败");
            }
            Long userId = context.getTarget();
            // 删除本地监听器记录
            healthMonitorRepository.removeByListenerId(id, userId);
            lbPoolRepository.removeByListenerId(id, userId);
            lbMemberRepository.removeByListenerId(id, userId);
            lbListenerRepository.remove(id, userId);
            return new BocloudResult(true, "删除成功");
        } catch (Exception e) {
            logger.error("remove lb Listener fail:", e);
            return new BocloudResult(false, "删除失败");
        }
    }

    @Override
    public BocloudResult remove(Long id, RequestContext context) {
        try {
            LbListener listener = lbListenerRepository.query(id);
            if (null == listener) {
                return new BocloudResult(false, "数据不存在");
            }
            LoadBalancer loadBalancer = loadBalancerRepository.query(listener.getLbId());
            if (null == loadBalancer) {
                return new BocloudResult(false, "监听器关联的负载均衡器不存在");
            }
            CloudVendor vendor = cloudVendorRepository.query(listener.getVendorId());
            if (null == vendor) {
                return new BocloudResult(false, "云平台不存在");
            }

            List<LbListener> listeners;
            BocloudResult result;
            switch (CloudProvider.valueOf(vendor.getType())) {
                case AWS:
                    listeners = lbListenerRepository.listByLbId(listener.getLbId());
                    if (listeners.size() == 1) {
                        return new BocloudResult(false, "每个负载均衡器最少需要一个监听器");
                    }
                    result = removeAWS(id, context, listener, vendor);
                    break;
                case HUAWEI:
                case HCSO:
                    result = removeHUAWEI(id, context, listener, vendor);
                    break;
                case ALIYUN:
                    result = removeALIYUN(id, context, listener, vendor);
                    break;
                case VOLCENGINE:
                    result = removeVOLCENGINE(id, context, listener, vendor);
                    break;
                default:
                    result = removeNormal(id, context, listener, vendor);
                    break;
            }
            return result;
        } catch (Exception e) {
            logger.error("remove lb Listener fail:", e);
            return new BocloudResult(false, "删除失败 : " + e.getMessage());
        }
    }

    private BocloudResult removeVOLCENGINE(Long id, RequestContext context, LbListener listener, CloudVendor vendor) {
        String path = LbListener.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            LbListener lbListener = lbListenerRepository.query(id);
            if (lbListener == null) {
                return new BocloudResult(false, "监听器不存在，请检查");
            }
            List<LbListenerRule> lbListenerRules = lbListenerRuleRepository.listByVid(lbListener.getVendorId(), listener.getRegionId(), lbListener.getListenerUuid());
            if (!ListTool.isEmpty(lbListenerRules) && lbListenerRules.size() > 1) {
                return new BocloudResult(false, "此监听器下存在转发规则，暂不支持删除");
            }
            BocloudResult result = lbDriver.removeListener(vendor.getUuid(), listener.getRegionId(), listener.getListenerUuid());
            if (result.isFailed()) {
                return new BocloudResult(false, "删除失败");
            }
            // 删除本地监听器记录
            lbListenerRepository.remove(id, context.getTarget());
            return new BocloudResult(true, "删除成功");
        } catch (Exception e) {
            logger.error("remove lb Listener fail:", e);
            return new BocloudResult(false, "删除失败");
        }
    }

    public BocloudResult removeNormal(Long id, RequestContext context, LbListener listener, CloudVendor vendor) {
        String path = LbListener.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            List<LbListener> listeners = lbListenerRepository.listByLbId(listener.getLbId());
            if (listeners.size() == 1) {
                return new BocloudResult(false, "每个负载均衡器最少需要一个监听器");
            }
            BocloudResult result = lbDriver.removeListener(vendor.getUuid(), null, listener.getListenerUuid());
            if (result.isFailed()) {
                return new BocloudResult(false, "删除失败");
            }
            Long userId = context.getTarget();
            // 删除本地监听器记录
            healthMonitorRepository.removeByListenerId(id, userId);
            lbPoolRepository.removeByListenerId(id, userId);
            lbMemberRepository.removeByListenerId(id, userId);
            lbListenerRepository.remove(id, userId);
            return new BocloudResult(true, "删除成功");
        } catch (Exception e) {
            logger.error("remove lb Listener fail:", e);
            return new BocloudResult(false, "删除失败");
        }
    }

    @Override
    public BocloudResult batchRemove(List<Long> idArray, RequestContext context) {
        if (ListTool.isEmpty(idArray)) {
            return new BocloudResult<>(false, "没有需要删除的负载均衡监听器！");
        }
        try {
            List<BocloudResult> succList = Lists.newArrayList();
            List<BocloudResult> failList = Lists.newArrayList();
            Long vendorId = null;
            for (Long id : idArray) {
                LbListener listener = lbListenerRepository.query(id);
                if (null != listener) {
                    if (null == vendorId) {
                        vendorId = listener.getVendorId();
                    }
                    BocloudResult result = remove(id, context);
                    if (result.isSuccess()) {
                        succList.add(new BocloudResult<>(true, "【" + listener.getName() + "】删除成功"));
                    } else {
                        failList.add(
                                new BocloudResult<>(false, "【" + listener.getName() + "】删除失败：" + result.getMessage()));
                    }
                }
            }
            CloudVendor vendor = cloudVendorRepository.query(vendorId);
            String operate = vendor.getType().toLowerCase() + ".listener";
            // 删除成功的数量
            int success = succList.size();
            // 删除失败的数量
            int fail = failList.size();
            String content = null;
            if (fail == idArray.size()) {
                content = "负载均衡监听器批量删除失败，详情如下：\n";
                for (BocloudResult bocloudResult : failList) {
                    content += bocloudResult.getMessage() + "\n";
                }
                resourceEventPublisher
                        .send(new OperateResult(false, content, operate, MapTools.simpleMap("vendorId", vendor.getId()),
                                OperateResult.OperateCategory.ResourceEvent, context));
            } else {
                content = "负载均衡监听器批量删除成功【" + success + "】个,失败【" + fail + "】个，详情如下：\n";
                for (BocloudResult bocloudResult : succList) {
                    content += bocloudResult.getMessage() + "\n";
                }
                for (BocloudResult bocloudResult : failList) {
                    content += bocloudResult.getMessage() + "\n";
                }
                resourceEventPublisher
                        .send(new OperateResult(true, content, operate, MapTools.simpleMap("vendorId", vendor.getId()),
                                OperateResult.OperateCategory.ResourceEvent, context));
            }
        } catch (Exception e) {
            logger.error("batch remove load balancer fail:", e);
            return new BocloudResult<>(false, "批量删除任务下发失败");
        }
        return new BocloudResult<>(true, "批量删除任务已下发，正在执行...");
    }

    @Override
    public BocloudResult listforPolicy(Long lbId, Long listenerId) {
        try {
            Assert.notNull(lbId,"负载均衡id不能为空");
            Assert.notNull(listenerId,"监听器id不能为空");
            List<LbListener> lbListeners = lbListenerRepository.listByLbId(lbId);
            // 文档引用：
//            只支持指定为protocol为TERMINATED_HTTPS的listener。
//            只支持指定为当前转发策略所在的负载均衡器下的监听器。
            List<LbListener> list = lbListeners.stream().filter(e -> StringUtils.equalsIgnoreCase(e.getProtocol(), "TERMINATED_HTTPS") || StringUtils.equalsIgnoreCase(e.getProtocol(), "HTTPS")).collect(Collectors.toList());
            return new BocloudResult(true, list, "查询成功");
        } catch (Exception e){
            logger.error("查询失败",e);
            return new BocloudResult(false,"查询失败");
        }
    }

}
