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.compute.ServerDriver;
import com.bocloud.cmp.driver.network.PortDriver;
import com.bocloud.cmp.entity.enums.CloudProvider;
import com.bocloud.cmp.model.*;
import com.bocloud.cmp.provider.utils.IPAddress;
import com.bocloud.common.model.*;
import com.bocloud.common.utils.*;
import com.bocloud.ims.entity.resource.*;
import com.bocloud.ims.entity.resource.Ip.IpStatus;
import com.bocloud.ims.interfaces.resource.PortService;
import com.bocloud.ims.interfaces.resource.VendorProjectService;
import com.bocloud.ims.repository.resource.*;
import com.bocloud.ims.service.transportor.OpenstackTransportor;
import com.bocloud.ims.service.transportor.PowervcTransportor;
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.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 端口Service接口实现
 *
 * @author dongkai
 */
@Service("portService")
public class PortServiceImpl implements PortService {

	private static Logger logger = LoggerFactory.getLogger(PortServiceImpl.class);
	@Autowired
	private PortRepository portRepository;
	@Autowired
	private CloudVendorRepository cloudVendorRepository;
	@Autowired
	private CloudServerRepository cloudServerRepository;
	@Autowired
	private PortDriver portDriver;
	@Autowired
	private NetworkRepository networkRepository;
	@Autowired
	private SubnetRepository subnetRepository;
	@Autowired
	private IpRepository ipRepository;
	@Autowired
	private IpPoolRepository ipPoolRepository;
	@Autowired
	private PortFixedIpRepository portFixedIpRepository;
	@Autowired
	private ResourceEventPublisher resourceEventPublisher;
	@Autowired
	private LockFactory lockFactory;
	@Autowired
	private PowervcTransportor powervcTransportor;
	@Autowired
	private ServerDriver serverDriver;
	@Autowired
	private VendorProjectService vendorProjectService;
	@Autowired
	private OSTenantRepository osTenantRepository;
	@Autowired
	private ResourceEventRepository resourceEventRepository;

	@Override
	public BocloudResult<GridBean<Port>> list(Pager pager) {
		GridBean gridBean = null;
		try {
			int page = pager.getPage();
			int rows = pager.getRows();
			List<Param> params = pager.getParams();
			Map<String, String> sorter = pager.getSorter();
			boolean simple = pager.getSimple();

			if (null == params) {
				params = new ArrayList<>();
			}
			if (null == sorter) {
				sorter = Maps.newHashMap();
			}
			sorter.put("gmtCreate", Common.ONE);
			int total = portRepository.count(params);
			if (simple) {
				List<SimpleBean> beans = portRepository.list(params, sorter);
				gridBean = new GridBean(1, 1, total, beans);
			} else {
				List<Port> list = this.portRepository.list(page, rows, params, sorter);
				for (Port port : list) {
					port.setPortFixedIps(portFixedIpRepository.listByPortUuid(port.getPortUuid()));
				}
				gridBean = GridHelper.getBean(page, rows, total, list);
			}
			return new BocloudResult<>(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("list port fail:", e);
			return new BocloudResult<>(false, "查询失败", null, null);
		}
	}

	@Override
	public BocloudResult create(Port port, RequestContext context) {
		String name = port.getName();
		Long networkId = port.getNetworkId();
		Long subnetId = port.getSubnetId();
		String ipAddress = port.getIpAddress();
		String deviceOwner = port.getDeviceOwner();
		try {
			Network network = networkRepository.query(networkId);
			if (null == network) {
				return new BocloudResult<>(false, "网络不存在");
			}
			CloudVendor vendor = cloudVendorRepository.query(network.getVendorId());
			if (null == vendor) {
				logger.error("get vendor failure!");
				return new BocloudResult<>(false, "执行失败!");
			}
			Subnet subnet = null;
			if (null != subnetId && 0L != subnetId) {
				subnet = subnetRepository.query(subnetId);
				if (null == subnet) {
					return new BocloudResult<>(false, "子网不存在");
				}
			}
			PortModel model = new PortModel();
			model.setName(name);
			model.setNetworkUuid(network.getNetworkUuid());

//			// 校验该IP是否在子网范围内
//			IpPool ipPool = ipPoolRepository.queryBySubnet(subnetId, subnet.getVendorId());
//			if (null == ipPool) {
//				ipPool = new IpPool(subnet.getGateway(), subnet.getCidr(), subnet.getIpPools(), subnet.getDnsNames(),
//						subnetId, network.getId(), subnet.getVendorId());
//				ipPool.setCreatorId(context.getTarget());
//				ipPool.setMenderId(context.getTarget());
//				ipPool.setVersion(IPAddress.getVersion(subnet.getGateway()));
//				ipPoolRepository.save(ipPool);
//			}
			List<String> pools = JSONArray.parseArray(subnet.getIpPools(), String.class);
			if (ListTool.isEmpty(pools)) {
				return new BocloudResult<>(false, "执行失败：该子网IP地址池分配有误");
			}
			List<PortFixedIpModel> portFixedIps = new ArrayList<>();
			if (!StringUtils.isEmpty(ipAddress)) {
				Ip ip = ipRepository.checkExist(ipAddress, subnetId, subnet.getVendorId());
				if (null != ip) {
					return new BocloudResult<>(false, "执行失败：该IP已被其他资源使用");
				}

				IPAddress address = IPAddress.getIPAddress(ipAddress);
				boolean flag = address.isInPools(ipAddress, pools);
				if (!flag) {
					return new BocloudResult<>(false, "执行失败：该IP不在该子网的网段内");
				}
				ip = new Ip(ipAddress, address.getMask(subnet.getCidr()), subnet.getCidr(), subnet.getDnsNames(),
						subnet.getVendorId(), IDFactory.instance().uuid(), null, IpStatus.used);
				ip.setCatalog("PORT");
				ip.setNetworkId(subnet.getNetworkId());
				ip.setSubnetId(subnet.getId());
				ipRepository.save(ip);
			} else {
				String startIp = subnet.getIpPools().substring(2, subnet.getIpPools().length() - 2).split("-")[0];
				String endIp = subnet.getIpPools().substring(2, subnet.getIpPools().length() - 2).split("-")[1];
				IPAddress address = IPAddress.getIPAddress(startIp);
				BigInteger ipstart = address.ipToInteger(startIp);// 获取起始IP的开始位置
				BigInteger ipend = address.ipToInteger(endIp);// 获取终止IP的结束位置
				Ip ip = new Ip();
				while (ipend.compareTo(ipstart) >= 0) {
					String ipKey = address.integerToIp(ipstart);
					ip = ipRepository.checkExist(ipKey, subnetId, subnet.getVendorId());
					if (ip != null) {
						ipstart = ipstart.add(new BigInteger("1"));
					} else {
						ipAddress = ipKey;
						break;
					}
				}
				ip = new Ip(ipAddress, address.getMask(subnet.getCidr()), subnet.getCidr(), subnet.getDnsNames(),
						subnet.getVendorId(), IDFactory.instance().uuid(), null, IpStatus.used);
				ip.setCatalog("PORT");
				ip.setNetworkId(subnet.getNetworkId());
				ip.setSubnetId(subnet.getId());
				ipRepository.save(ip);
				if (StringUtils.isEmpty(ipAddress)) {
					return new BocloudResult<>(false, "此子网下无IP可分配");
				}

			}
			if (null != subnet) {
				portFixedIps.add(new PortFixedIpModel(ipAddress, subnet.getSubnetUuid()));
			}
			model.setPortFixedIps(portFixedIps);
			if (CloudProvider.POWERVC.name().equals(vendor.getType())) {
				model.setDeviceOwner(deviceOwner);
				model.setDeviceUuid("Lock");
			}
			BocloudResult result = null;
			TenantProvider provider = vendorProjectService.getAncestorProject(vendor.getId(), context.getTenant());
			if (null == provider) {
				OSTenant osTenant = osTenantRepository.getByTenantUuid(network.getTenantUuid(), network.getVendorId());
				if (null != osTenant) {
					result = portDriver.create(vendor.getUuid(), osTenant.getName(), null, model);
				} else {
					result = portDriver.create(vendor.getUuid(), null, model);
				}
			} else {
				result = portDriver.create(vendor.getUuid(), provider.getProjectName(), null, model);
			}
			if (result.isFailed()) {
				if (!StringUtils.isEmpty(ipAddress)) {
					ipRepository.delete(ipAddress, subnetId, vendor.getId());
				}
				return new BocloudResult<>(false, "执行失败:" + result.getMessage());
			}
			PortModel portModel = (PortModel) result.getData();
			if (CloudProvider.POWERVC.name().equals(vendor.getType())) {
				powervcTransportor.insertOrUpdate(vendor, portModel, context.getTarget());
				for (PortFixedIpModel portFixedIp : portModel.getPortFixedIps()) {
					Subnet subnetOfPortFixedIp = subnetRepository.getBySubId(portFixedIp.getSubnetUuid());
					powervcTransportor.insertOrUpdate(subnetOfPortFixedIp, portFixedIp.getIpAddress(),
							context.getTarget());
				}
				return new BocloudResult<>(true, "执行成功");
			}
			port = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), Port.class);
			port.preSave(context.getTarget(), context.getTarget(), vendor.getId(), networkId);
			portRepository.save(port);
			if (CloudProvider.OPENSTACK.name().equals(vendor.getType())
					|| CloudProvider.FUSIONCLOUD.name().equals(vendor.getType())
					|| CloudProvider.MANAGEONE.name().equals(vendor.getType())
					|| CloudProvider.HUAWEI.name().equals(vendor.getType())) {
				OpenstackTransportor toolOS = new OpenstackTransportor(ipRepository, ipPoolRepository, subnetRepository,
						portFixedIpRepository);
				toolOS.batchSavePortFixedIp(portModel.getPortFixedIps(), port.getPortUuid(), port.getId(),
						vendor.getId());
			}
			return new BocloudResult<>(true, "执行成功!");
		} catch (Exception e) {
			logger.error("create port failure:", e);
			return new BocloudResult<>(false, "执行失败!");
		}
	}

	@Override
	public BocloudResult modify(String params, RequestContext context) {
		JSONObject object = JSONTools.isJSONObj(params);
		Long id = object.getLong(Common.ID);
		String name = object.getString(Common.NAME);
		String deviceOwner = object.getString("deviceOwner");
		try {
			Port port = portRepository.query(id);
			port.setPortFixedIps(portFixedIpRepository.listByPortUuid(port.getPortUuid()));
			if (!StringUtils.isEmpty(name)) {
				port.setName(name);
			}
			if (!StringUtils.isEmpty(deviceOwner)) {
				port.setDeviceOwner(deviceOwner);
			}
			CloudVendor vendor = cloudVendorRepository.query(port.getVendorId());
			if (null == vendor) {
				logger.error("get vendor failure!");
				return new BocloudResult<>(false, "修改失败!");
			}
			Network network = networkRepository.query(port.getNetworkId());
			if (null == network) {
				return new BocloudResult<>(false, "网络不存在");
			}
			PortModel model = new PortModel();
			model.setPortId(port.getId());
			model.setName(name);
			model.setPortUuid(port.getPortUuid());
			model.setNetworkUuid(port.getNetworkUuid());
			model.setDeviceOwner(deviceOwner);
			if (CloudProvider.POWERVC.name().equals(vendor.getType())
					|| CloudProvider.MANAGEONE.name().equals(vendor.getType())) {
				String ipAddress = object.getString("ipAddress");
				if (ipAddress != null) {
					// 需要调整ip地址
					List<Subnet> subnets = subnetRepository.list(vendor.getId(), network.getId());
					if (subnets.size() == 0) {
						return new BocloudResult<>(false, "修改失败，因为当前网络为DHCP网络，您可以将该网络修改为静态网络后再试");
					}
					if (StringUtils.isEmpty(ipAddress)) {
						// 调整为自动获取ip地址
						model.setPortFixedIps(new ArrayList<>());
					} else {
						// 调整为另一个ip地址
						Subnet subnet = subnetRepository.query(subnets.get(0).getId());
						if (subnet == null) {
							return new BocloudResult<>(false, "修改失败：未找到子网");
						}
						// 检查ip地址的有效性
						List<PortFixedIp> portFixedIps = portFixedIpRepository.listByPortId(id);
						if (portFixedIps == null || portFixedIps.size() == 0
								|| !ipAddress.equals(portFixedIps.get(0).getIpAddress())) {
							// 检测ip地址占用
							Ip ip = ipRepository.checkExist(ipAddress, subnets.get(0).getId(), vendor.getId());
							if (ip != null) {
								return new BocloudResult<>(false, "修改失败：该IP已被其他资源使用");
							}
							// 检测ip是否在网络范围内
							boolean isInRange = IPAddress.getIPAddress(ipAddress).isInPools(ipAddress,
									JSON.parseArray(subnet.getIpPools(), String.class));
							if (!isInRange) {
								return new BocloudResult<>(false, "修改失败：该IP不在该子网的网段内");
							}
						}
						PortFixedIpModel portFixedIpModel = new PortFixedIpModel();
						portFixedIpModel.setIpAddress(ipAddress);
						portFixedIpModel.setSubnetUuid(subnet.getSubnetUuid());
						model.setPortFixedIps(Collections.singletonList(portFixedIpModel));
					}
				}
			} else {
				if (!ListTool.isEmpty(port.getPortFixedIps())) {
					List<PortFixedIpModel> portFixedIps = new ArrayList<>();
					for (PortFixedIp portFixedip : port.getPortFixedIps()) {
						portFixedIps.add(new PortFixedIpModel(portFixedip.getIpAddress(), portFixedip.getSubnetUuid()));
					}
					model.setPortFixedIps(portFixedIps);
				}
			}
			BocloudResult result = portDriver.modify(vendor.getUuid(), null, model);
			if (result.isFailed()) {
				return new BocloudResult<>(false, "修改失败!");
			}
			if (CloudProvider.POWERVC.name().equals(vendor.getType())) {
				String ipAddress = object.getString("ipAddress");
				PortModel portModel = (PortModel) result.getData();
				portFixedIpRepository.deleteByPortId(port.getId());
				ipRepository.deleteByPortId(port.getId());
				powervcTransportor.insertOrUpdate(vendor, portModel, context.getTarget());
				for (PortFixedIpModel portFixedIp : portModel.getPortFixedIps()) {
					Subnet subnet = subnetRepository.getBySubId(portFixedIp.getSubnetUuid());
					if (subnet == null) {
						return new BocloudResult<>(false, "未找到子网");
					}
					powervcTransportor.insertOrUpdate(subnet, portFixedIp.getIpAddress(), context.getTarget());
				}
				new Thread(() -> {
					long start = System.currentTimeMillis();
					while (System.currentTimeMillis() - start < 1 * 60 * 1000) {
						BocloudResult getResult = serverDriver.detail(port.getDeviceUuid(), vendor.getUuid(), null);
						if (getResult.isSuccess()) {
							ServerModel serverModel = (ServerModel) getResult.getData();
							JSONArray jsonArray = JSONArray.parseArray(serverModel.getPrivateIps());
							for (Object ip : jsonArray) {
								JSONObject ipObject = (JSONObject) ip;
								if (ipObject.getString("networkName").equals(network.getName())
										&& ipObject.getString("address").equals(ipAddress)) {
									try {
										powervcTransportor.insertOrUpdate(vendor, serverModel, context.getTarget());
									} catch (Exception e) {
										logger.error("延迟更新虚拟机ip信息失败：", e);
									}
									logger.debug("延迟更新虚拟机ip信息成功");
									break;
								}
							}
						} else {
							logger.error("延迟更新虚拟机ip信息失败：", getResult.getMessage());
						}
						try {
							logger.debug("正在延迟更新虚拟机ip信息，3秒后重试...");
							Thread.sleep(3000);
						} catch (InterruptedException e) {
							logger.error("延迟更新虚拟机ip信息失败：", e);
							Thread.currentThread().interrupt();
						}
					}
				}).start();
			} else {
				CloudProvider provider = CloudProvider.valueOf(vendor.getType());
				if (CloudProvider.MANAGEONE == provider) {
					String ipAddress = object.getString("ipAddress");
					if (!StringUtils.isEmpty(ipAddress)) {
						PortFixedIp portFixedIp = portFixedIpRepository.getByPortIdAndIp(port.getId(),
								object.getString("oldIpAddress"));
						portFixedIp.setIpAddress(object.getString("ipAddress"));
						portFixedIpRepository.update(portFixedIp);
						CloudServer cloudServer = cloudServerRepository.query(object.getLong("vmId"));
						String privateIps = cloudServer.getPrivateIps();
						// 设置内网IP
						List<NetworkBean> networkBeans = JSON.parseArray(privateIps, NetworkBean.class);
						for (NetworkBean networkBean : networkBeans) {
							List<AddressBean> addresses = networkBean.getAddresses();
							if (!ListTool.isEmpty(addresses)) {
								for (AddressBean addressBean : addresses) {
									if (addressBean.getPortUuid().equalsIgnoreCase(port.getPortUuid())) {
										addressBean.setAddress(object.getString("ipAddress"));
										break;
									}
								}
							}
						}
						cloudServer.setPrivateIps(JSON.toJSONString(networkBeans));
						cloudServerRepository.update(cloudServer);
						// 需要调整ip地址
						List<Subnet> subnets = subnetRepository.list(vendor.getId(), network.getId());
						Ip ip = ipRepository.checkExist(object.getString("oldIpAddress"), subnets.get(0).getId(),
								vendor.getId());
						if (null != ip) {
							ip.setIp(object.getString("ipAddress"));
							ipRepository.update(ip);
						}
						ResourceEvent event = new ResourceEvent(cloudServer.getId(), "IP编辑",
								result.isSuccess() ? "成功" : "失败", context.getTarget(), new Date(), "VM", vendor.getId(),
								context.getCatalog());
						resourceEventRepository.save(event);
					}
					if (!StringUtils.isEmpty(name)) {
						port.setName(name);
						portRepository.update(port);
					}
				} else {
					portRepository.update(port);
				}
			}
			return new BocloudResult<>(true, "修改成功!");
		} catch (Exception e) {
			logger.error("create port failure:", e);
			return new BocloudResult<>(false, "修改失败!");
		}
	}

	@Override
	public BocloudResult remove(Long id, RequestContext context) {
		String path = Port.class.getSimpleName() + "_" + id;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			Port port = portRepository.query(id);
			if (null == port) {
				logger.warn("port data not exist");
				return new BocloudResult<>(false, "数据不存在");
			}
			// 云供应商
			CloudVendor vendor = cloudVendorRepository.query(port.getVendorId());
			if (null == vendor) {
				logger.error("get vendor failure");
				return new BocloudResult<>(false, "执行失败");
			}
			BocloudResult result = portDriver.remove(port.getPortUuid(), vendor.getUuid(), "");
			if (result.isFailed()) {
				return new BocloudResult<>(false, "执行失败:" + result.getMessage());
			}
			List<PortFixedIp> fixedIps = portFixedIpRepository.listByPortUuid(port.getPortUuid());
			for (PortFixedIp fixedIp : fixedIps) {
				ipRepository.delete(fixedIp.getIpAddress(), fixedIp.getSubnetId(), port.getVendorId());
			}
			portFixedIpRepository.deleteByPortId(id);
			boolean flag = portRepository.remove(id, context.getTarget());
			if (flag) {
				updateServer(port.getDeviceUuid());
			}
			return new BocloudResult<>(true, "执行成功");
		} catch (Exception e) {
			logger.error("remove port fail:", e);
			return new BocloudResult<>(false, "执行失败");
		}
	}

	private void updateServer(String deviceUuid) throws Exception {
		if (StringUtils.isEmpty(deviceUuid)) {
			return;
		}
		// 更新和此端口绑定的虚拟机内网IP
		CloudServer server = cloudServerRepository.getByInstanceId(deviceUuid);
		if (null == server) {
			return;
		}
		// 设置内网IP
		List<NetworkBean> networkBeans = Lists.newArrayList();
		// key networkUuid
		Map<String, List<Port>> portMap = Maps.newHashMap();
		String privateIps = "";
		List<Port> ports = portRepository.listByDeviceId(server.getInstanceId(), server.getVendorId());
		for (Port port : ports) {
			port.setPortFixedIps(portFixedIpRepository.listByPortUuid(port.getPortUuid()));
			if (portMap.containsKey(port.getNetworkUuid())) {
				List<Port> list = portMap.get(port.getNetworkUuid());
				list.add(port);
			} else {
				List<Port> list = Lists.newArrayList();
				list.add(port);
				portMap.put(port.getNetworkUuid(), list);
			}
		}
		for (String key : portMap.keySet()) {
			List<Port> portList = portMap.get(key);
			if (portList.isEmpty()) {
				continue;
			}
			Network network = networkRepository.getByNetId(key);
			if (null == network) {
				continue;
			}
			NetworkBean networkBean = new NetworkBean(network.getId(), network.getName(), network.getNetworkUuid());
			List<AddressBean> addresses = Lists.newArrayList();
			for (Port port : portList) {
				List<PortFixedIp> portFixedIps = port.getPortFixedIps();
				if (ListTool.isEmpty(portFixedIps)) {
					continue;
				}
				for (PortFixedIp fixedIp : portFixedIps) {
					Subnet subnet = subnetRepository.getBySubId(fixedIp.getSubnetUuid());
					if (null == subnet) {
						continue;
					}
					AddressBean address = new AddressBean(subnet.getId(), subnet.getName(), network.getId(),
							subnet.getSubnetUuid(), port.getId(), port.getPortUuid(), fixedIp.getIpAddress());
					addresses.add(address);
				}
			}
			networkBean.setAddresses(addresses);
			if (!addresses.isEmpty()) {
				networkBeans.add(networkBean);
			}
		}
		if (networkBeans.isEmpty()) {
			privateIps = null;
		} else {
			privateIps = JSONObject.toJSONString(networkBeans);
		}
		server.setPrivateIps(privateIps);
		cloudServerRepository.update(server);
	}

	@Override
	public BocloudResult<Port> detail(Long id) {
		try {
			Port port = portRepository.query(id);
			return new BocloudResult<>(true, port, "查询成功!");
		} catch (Exception e) {
			logger.error("query port detail failure:", e);
			return new BocloudResult<>(false, "查询详情失败!");
		}
	}

	@Override
	public BocloudResult<List<Port>> listExtranetByVmId(String params) {
		JSONObject object = JSONTools.isJSONObj(params);
		if (null == object) {
			return new BocloudResult<>(false, "参数异常");
		}
		Long vendorId = object.getLong(Common.VENDORID);// 云平台ID
		Long vmId = object.getLong("vmId");// 虚拟机ID
		try {
			// 云供应商
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			if (null == vendor) {
				logger.error("get vendor failure");
				return new BocloudResult<>(false, "云平台不存在");
			}
			// 虚拟机
			CloudServer server = cloudServerRepository.query(vmId);
			if (null == server) {
				logger.error("get cloud server failure");
				return new BocloudResult<>(false, "虚拟机不存在");
			}
			List<Port> ports = portRepository.listExtranetByDeviceId(server.getInstanceId(), vendorId);
			return new BocloudResult<>(true, ports, "查询成功!");
		} catch (Exception e) {
			logger.error("list extranet port fail:", e);
			return new BocloudResult<>(false, "查询失败!");
		}
	}

	@Override
	public BocloudResult<List<Port>> listByNetworkId(String params) {
		JSONObject object = JSONTools.isJSONObj(params);
		if (null == object) {
			return new BocloudResult<>(false, "参数异常");
		}
		try {
			List<Port> ports = portRepository.listByNetworkId(object.getLong("networkId"));
			return new BocloudResult<>(true, ports, "查询成功!");
		} catch (Exception e) {
			logger.error("list extranet port fail:", e);
			return new BocloudResult<>(false, "查询失败!");
		}
	}

	@Override
	public BocloudResult batchRemove(List<Long> ids, RequestContext context) {
		if (ListTool.isEmpty(ids)) {
			return new BocloudResult<>(false, "没有需要删除的端口！");
		}
		try {
			List<BocloudResult> succList = Lists.newArrayList();
			List<BocloudResult> failList = Lists.newArrayList();
			Long vendorId = null;
			for (Long id : ids) {
				Port port = portRepository.query(id);
				if (null != port) {
					if (null == vendorId) {
						vendorId = port.getVendorId();
					}
					BocloudResult result = remove(id, context);
					if (result.isSuccess()) {
						succList.add(new BocloudResult<>(true, "【" + port.getName() + "】删除成功"));
					} else {
						failList.add(new BocloudResult<>(false, "【" + port.getName() + "】删除失败：" + result.getMessage()));
					}
				}
			}
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			String operate = vendor.getType().toLowerCase() + ".port";
			// 删除成功的数量
			int success = succList.size();
			// 删除失败的数量
			int fail = failList.size();
			String content = null;
			if (fail == ids.size()) {
				content = "端口批量删除失败，详情如下：\n";
				for (BocloudResult bocloudResult : failList) {
					content += bocloudResult.getMessage() + "\n";
				}
				resourceEventPublisher.send(
						new OperateResult(false, content, operate, MapTools.simpleMap(Common.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(Common.VENDORID, vendor.getId()),
								OperateResult.OperateCategory.ResourceEvent, context));
			}
		} catch (Exception e) {
			logger.error("batch remove port fail:", e);
			return new BocloudResult<>(false, "批量删除任务下发失败");
		}
		return new BocloudResult<>(true, "批量删除任务已下发，正在执行...");
	}

	@Override
	public BocloudResult<List<Port>> listByVmId(String params) {
		JSONObject object = JSONTools.isJSONObj(params);
		if (null == object) {
			return new BocloudResult<>(false, "参数异常");
		}
		Long vmId = object.getLong("id");// 虚拟机ID
		if (vmId == null) {
			vmId = object.getLong("vmId");
		}
		try {
			List<Port> ports = portRepository.listByVmId(vmId);
			return new BocloudResult<>(true, ports, "查询成功!");
		} catch (Exception e) {
			logger.error("list extranet port fail:", e);
			return new BocloudResult<>(false, "查询失败!");
		}
	}
}
