package com.bocloud.ims.service.resource;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.network.VpnDriver;
import com.bocloud.cmp.model.VpnModel;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.GridBean;
import com.bocloud.common.model.OperateResult;
import com.bocloud.common.model.Pager;
import com.bocloud.common.model.RequestContext;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.common.utils.JSONTools;
import com.bocloud.common.utils.MapTools;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.OSTenant;
import com.bocloud.ims.entity.resource.Router;
import com.bocloud.ims.entity.resource.Subnet;
import com.bocloud.ims.entity.resource.Vpn;
import com.bocloud.ims.entity.resource.VpnConn;
import com.bocloud.ims.interfaces.resource.VpnService;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.repository.resource.OSTenantRepository;
import com.bocloud.ims.repository.resource.RouterRepository;
import com.bocloud.ims.repository.resource.SubnetRepository;
import com.bocloud.ims.repository.resource.VpnConnRepository;
import com.bocloud.ims.repository.resource.VpnRepository;
import com.bocloud.ims.service.utils.ResourceEventPublisher;
import com.bocloud.service.lock.BocloudACLock;
import com.bocloud.service.lock.LockFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 硬盘备份
 *
 * @author Administrator
 */
@Service("vpnService")
public class VpnServiceImpl implements VpnService {

	private static Logger logger = LoggerFactory.getLogger(VpnServiceImpl.class);
	@Autowired
	private VpnRepository vpnRepository;
	@Autowired
	private LockFactory lockFactory;
	@Autowired
	private CloudVendorRepository cloudVendorRepository;
	@Autowired
	private SubnetRepository subnetRepository;
	@Autowired
	private RouterRepository routerRepository;
	@Autowired
	private VpnDriver vpnDriver;
	/*
	 * @Autowired private GwQosDriver gwQosDriver;
	 */
	@Autowired
	private VpnConnRepository vpnConnRepository;
	@Autowired
	private OSTenantRepository osTenantRepository;
	@Autowired
	private ResourceEventPublisher resourceEventPublisher;

	@Override
	public BocloudResult<GridBean<Vpn>> list(Pager pager, RequestContext context) {
		try {
			Long tenantId = context.getTenant();
			int total = this.vpnRepository.count(pager.getParams(), tenantId);
			List<Vpn> list = this.vpnRepository.list(pager.getPage(), pager.getRows(), pager.getParams(),
					pager.getSorter(), tenantId);
			GridBean gridBean = GridHelper.getBean(pager.getPage(), pager.getRows(), total, list);
			return new BocloudResult<>(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("Query error:", e);
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@Override
	public BocloudResult<List<Vpn>> condition(String condition, RequestContext context) {
		try {
			if (!StringUtils.isEmpty(condition)) {
				JSONObject object = JSONObject.parseObject(condition);
				if ("listbyvendor".equalsIgnoreCase(object.getString("condition"))) {
					return this.listByVendor(object.getLong(Common.VENDORID));
				} else if ("listusable".equalsIgnoreCase(object.getString("condition"))) {
					return this.listUsable(condition, context);
				}
			}
			return new BocloudResult<>(false, "查询失败");
		} catch (Exception e) {
			logger.error("Query error:", e);
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@Override
	public BocloudResult<String> create(Vpn vpn, RequestContext context) {
		if (null == vpn) {
			return new BocloudResult<>(false, "参数格式错误");
		}
		Long vendorId = vpn.getVendorId();
		Long subnetId = vpn.getSubnetId();
		Long routerId = vpn.getRouterId();
		String name = vpn.getName();
		String remark = vpn.getRemark();
		String vpnType = vpn.getVpnType();
		try {
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			if (null == vendor) {
				return new BocloudResult<>(false, "指定的地域下云平台不存在");
			}
			Subnet subnet = subnetRepository.query(subnetId);
			if (null == subnet) {
				return new BocloudResult<>(false, "子网不存在");
			}
			Router router = routerRepository.query(routerId);
			if (null == router) {
				return new BocloudResult<>(false, "路由数据不存在");
			}
			new Thread(() -> {
				String operate = vendor.getType().toLowerCase() + ".vpn";
				try {
					VpnModel model = new VpnModel();
					model.setSubnetUuid(subnet.getSubnetUuid());
					model.setRouterUuid(router.getRouterUuid());
					model.setName(name);
					model.setRemark(remark);
					model.setAdminStateUp(true);
					model.setVpnType(vpnType);
					BocloudResult result = vpnDriver.create(model, vendor.getUuid(), vpn.getOsTenantName(), null);
					if (result.isSuccess()) {
						Vpn vpnInfo = new Vpn();
						VpnModel vpnModel = (VpnModel) result.getData();
						BeanUtils.copyProperties(vpnModel, vpnInfo);
						vpnInfo.setVpnUuid(vpnModel.getVpnUuid());
						vpnInfo.setSubnetId(subnet.getId());
						vpnInfo.setRouterId(router.getId());
						vpnInfo.setCreatorId(context.getTarget());
						vpnInfo.setMenderId(context.getTarget());
						vpnInfo.setRouterCode(router.getName());
						vpnInfo.setOwnerId(context.getTarget());
						vpnInfo.setTenantId(context.getTenant());
						vpnInfo.setVendorId(vendorId);
						vpnRepository.save(vpnInfo);
					}
					resourceEventPublisher.send(new OperateResult(result.isSuccess(), result.getMessage(), operate,
							MapTools.simpleMap(Common.VENDORID, vendorId), OperateResult.OperateCategory.ResourceEvent,
							context));
				} catch (Exception e) {
					resourceEventPublisher.send(
							new OperateResult(false, "VPN创建失败", operate, MapTools.simpleMap(Common.VENDORID, vendorId),
									OperateResult.OperateCategory.ResourceEvent, context));
				}
			}).start();
			return new BocloudResult<>(true, "VPN创建任务已下发，正在执行...");
		} catch (Exception e) {
			logger.error("Get error message：{}", e);
			return new BocloudResult<>(false, "VPN创建失败");
		}
	}

	@Override
	public BocloudResult<Vpn> modify(Vpn vpn, RequestContext context) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public BocloudResult<String> remove(Long id, RequestContext context) {
		String path = Vpn.class.getSimpleName() + "_" + id;
		boolean result = false;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			Vpn vpn = vpnRepository.query(id);
			if (null == vpn) {
				logger.warn("certificate data not exist");
				return new BocloudResult<>(false, "数据不存在");
			}
			VpnConn vpnConn = vpnConnRepository.queryByVpnUuid(vpn.getVpnUuid());
			if (null != vpnConn) {
				return new BocloudResult<>(false, "当前VPN正在使用中！");
			}
			CloudVendor vendor = cloudVendorRepository.query(vpn.getVendorId());
			if (null == vendor) {
				return new BocloudResult<>(false, "未找到云平台");
			}
			BocloudResult bocloudResult = vpnDriver.remove(vpn.getVpnUuid(), vendor.getUuid(), null);
			if (bocloudResult.isSuccess()) {
				// BocloudResult gwQosResult = gwQosDriver.remove(vpn.getGwqosUuid(),
				// vendor.getUuid());
				result = vpnRepository.remove(id, context.getTarget());
				/*
				 * if (gwQosResult.isFailed()) { logger.info("带宽解绑失败！"); }
				 */
			}
			return result ? new BocloudResult<>(true, "删除成功") : new BocloudResult<>(false, "删除失败");
		} catch (Exception e) {
			logger.error("delete certificate fail:", e);
			return new BocloudResult<>(false, "修改失败");
		}
	}

	@Override
	public BocloudResult<Vpn> detail(Long id) {
		try {
			Vpn vpn = vpnRepository.query(id);
			if (null == vpn) {
				logger.warn("certificate data not exist");
				return new BocloudResult<>(false, "数据不存在");
			}
			// 云供应商
			CloudVendor vendor = cloudVendorRepository.query(vpn.getVendorId());
			if (null == vendor) {
				logger.error("get cloudVendor failure");
				return new BocloudResult<>(false, "查询失败");
			}
			if (!org.springframework.util.StringUtils.isEmpty(vpn.getTenantUuid())) {
				OSTenant osTenant = osTenantRepository.getByTenantUuid(vpn.getTenantUuid(), vpn.getVendorId());
				if (null != osTenant) {
					vpn.setOsTenantName(osTenant.getName());
				}
			}
			return new BocloudResult<>(true, vpn, "查询详情成功");
		} catch (Exception e) {
			logger.error("query volume detail fail:", e);
			return new BocloudResult<>(false, "查询详情失败");
		}
	}

	@Override
	public BocloudResult<List<Vpn>> listByVendor(Long vendorId) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public BocloudResult<List<Vpn>> listUsable(String params, RequestContext context) {
		try {
			JSONObject object = JSONTools.isJSONObj(params);
			Long vendorId = object.getLong(Common.VENDORID);
			// 云供应商
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			if (null == vendor) {
				logger.error("get cloudVendor failure");
				return new BocloudResult<>(false, "查询失败");
			}
			List<Vpn> vpnList = vpnRepository.listUsable(vendorId, object.getString("tenantUuid"), context.getTenant());
			return new BocloudResult<List<Vpn>>(true, vpnList, "查询成功");
		} catch (Exception e) {
			logger.error("query vpn list fail:", e);
			return new BocloudResult<>(false, "查询失败");
		}
	}
}
