package com.bocloud.ims.service.resource;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.network.VpnDriver;
import com.bocloud.cmp.model.VpnPolicyModel;
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.VpnPolicy;
import com.bocloud.ims.interfaces.resource.VpnPolicyService;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.repository.resource.OSTenantRepository;
import com.bocloud.ims.repository.resource.VpnPolicyRepository;
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.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * vpn 策略
 *
 * @author Administrator
 */
@Service("vpnPolicyService")
public class VpnPolicyServiceImpl implements VpnPolicyService {

	private static Logger logger = LoggerFactory.getLogger(VpnPolicyServiceImpl.class);

	@Autowired
	private VpnPolicyRepository vpnPolicyRepository;
	@Autowired
	private CloudVendorRepository cloudVendorRepository;
	@Autowired
	private OSTenantRepository osTenantRepository;
	@Autowired
	private VpnDriver vpnDriver;
	@Autowired
	private ResourceEventPublisher resourceEventPublisher;
	@Autowired
	private LockFactory lockFactory;

	@Override
	public BocloudResult<GridBean<VpnPolicy>> list(Pager pager, RequestContext context) {
		try {
			Long tenantId = context.getTenant();
			int total = this.vpnPolicyRepository.count(pager.getParams(), tenantId);
			List<VpnPolicy> list = this.vpnPolicyRepository.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<VpnPolicy>> condition(String condition, RequestContext context) {
		try {
			if (!StringUtils.isEmpty(condition)) {
				JSONObject object = JSONObject.parseObject(condition);
				if ("listusablepolicy".equalsIgnoreCase(object.getString("condition"))) {
					return this.listUsablePolicy(condition);
				}
			}
            return new BocloudResult<>(false, "查询失败");
		} catch (Exception e) {
			logger.error("Query error:", e);
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@Override
	public BocloudResult<String> create(VpnPolicy vpnPolicyInfo, RequestContext context) {
		if (null == vpnPolicyInfo) {
			return new BocloudResult<>(false, "参数格式错误");
		}
		VpnPolicyModel vpnPolicyModel = JSONObject.parseObject(JSON.toJSONString(vpnPolicyInfo), VpnPolicyModel.class);
		try {
			Long vendorId = vpnPolicyModel.getVendorId();
			CloudVendor cloudVendor = cloudVendorRepository.query(vendorId);
			if (null == cloudVendor) {
				return new BocloudResult<>(false, "平台信息不存在！");
			}
			new Thread(() -> {
				BocloudResult bocloudResult = new BocloudResult<>(false, "创建失败！");
				String category = vpnPolicyModel.getCategory();
				String content = "创建" + category + "策略成功!";
				try {
					if ("IKE".equalsIgnoreCase(category)) {
						bocloudResult = vpnDriver.createIkePolicy(vpnPolicyModel, cloudVendor.getUuid(),
								vpnPolicyModel.getOsTenantName(), null);
					} else if ("IPSEC".equalsIgnoreCase(category)) {
						bocloudResult = vpnDriver.createIPsecPolicy(vpnPolicyModel, cloudVendor.getUuid(),
								vpnPolicyModel.getOsTenantName(), null);
					}
					if (bocloudResult.isSuccess()) {
						VpnPolicyModel vpnPolicyModel1 = (VpnPolicyModel) bocloudResult.getData();
						VpnPolicy vpnPolicy = new VpnPolicy();
						BeanUtils.copyProperties(vpnPolicyModel1, vpnPolicy);
						vpnPolicy.setCategory(vpnPolicyModel1.getCategory());
						vpnPolicy.setTenantId(context.getTenant());
						vpnPolicy.setVendorId(cloudVendor.getId());
						vpnPolicy.setGmtModify(new Date());
						vpnPolicy.setCreatorId(context.getTarget());
						vpnPolicy.setMenderId(context.getTarget());
						vpnPolicy.setStatus("NORMAL");
						vpnPolicy.setOwnerId(context.getTarget());
						vpnPolicyRepository.save(vpnPolicy);
					} else {
						content = bocloudResult.getMessage();
					}
				} catch (Exception e) {
					content = e.getMessage();
				}
				String operate = cloudVendor.getType().toLowerCase() + "." + category.toLowerCase() + "Policy";
				resourceEventPublisher.send(new OperateResult(bocloudResult.isSuccess(), content, operate,
						MapTools.simpleMap(Common.VENDORID, cloudVendor.getId()),
						OperateResult.OperateCategory.ResourceEvent, context));
			}).start();
			return new BocloudResult<>(true, "任务已经下发，正在执行……");
		} catch (Exception e) {
			logger.error("create network failure:", e);
			return new BocloudResult<>(false, "创建失败!");
		}
	}

	@Override
	public BocloudResult<VpnPolicy> modify(VpnPolicy vpnPolicy, RequestContext context) {
		String path = VpnPolicy.class.getSimpleName() + "_" + vpnPolicy.getId();
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			VpnPolicy policy = vpnPolicyRepository.query(vpnPolicy.getId());
			if (null == policy) {
				logger.warn("network data not exist");
				return new BocloudResult<>(false, "数据不存在");
			}
			// 云供应商
			CloudVendor vendor = cloudVendorRepository.query(policy.getVendorId());
			if (null == vendor) {
				logger.error("get cloud vendor failure");
				return new BocloudResult<>(false, "修改策略失败");
			}
			new Thread(() -> {
				String content = "编辑成功!";
				String category = "";
				BocloudResult bocloudResult = new BocloudResult<>(false, "编辑失败！");
				try {
					VpnPolicyModel vpnPolicyModel = new VpnPolicyModel();
					BeanUtils.copyProperties(vpnPolicy, vpnPolicyModel);
					category = vpnPolicyModel.getCategory();
					if ("IKE".equalsIgnoreCase(category)) {
						bocloudResult = vpnDriver.modfiyIkePolicy(vpnPolicyModel, vendor.getUuid(), null);
					} else if ("IPSEC".equalsIgnoreCase(category)) {
						bocloudResult = vpnDriver.modfiyIPsecPolicy(vpnPolicyModel, vendor.getUuid(), null);
					}
					if (bocloudResult.isSuccess()) {
						VpnPolicyModel model = (VpnPolicyModel) bocloudResult.getData();
						model.setVendorId(vpnPolicy.getVendorId());
						model.setCategory(vpnPolicy.getCategory());
						BeanUtils.copyProperties(model, policy);
						policy.setGmtModify(new Date());
						policy.setMenderId(context.getTarget());
						vpnPolicyRepository.update(policy);
					} else {
						content = bocloudResult.getMessage();
					}
				} catch (Exception e) {
					content = bocloudResult.getMessage();
				}
				String operate = vendor.getType().toLowerCase() + "." + category.toLowerCase() + "Policy";
				resourceEventPublisher.send(new OperateResult(bocloudResult.isSuccess(), content, operate,
						MapTools.simpleMap(Common.VENDORID, vendor.getId()),
						OperateResult.OperateCategory.ResourceEvent, context));
			}).start();
			return new BocloudResult<>(true, policy, "任务已下发，正在执行....");
		} catch (Exception e) {
			logger.error("modify network fail:", e);
			return new BocloudResult<>(false, "修改策略失败");
		}
	}

	@Override
	public BocloudResult<String> remove(Long id, RequestContext context) {
		String path = VpnPolicy.class.getSimpleName() + "_" + id;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			VpnPolicy policy = vpnPolicyRepository.query(id);
			if (null == policy) {
				logger.warn("network data not exist");
				return new BocloudResult<>(false, "数据不存在");
			}
			// 云供应商
			CloudVendor vendor = cloudVendorRepository.query(policy.getVendorId());
			if (null == vendor) {
				logger.error("get cloud vendor failure");
				return new BocloudResult<>(false, "修改策略失败");
			}
			BocloudResult bocloudResult = new BocloudResult<>(false, "删除失败！");
			String category = policy.getCategory();
			if ("IKE".equalsIgnoreCase(category)) {
				bocloudResult = vpnDriver.removeIkePolicy(policy.getPolicyUuid(), vendor.getUuid(), null);
			} else if ("IPSEC".equalsIgnoreCase(category)) {
				bocloudResult = vpnDriver.removeIPsecPolicy(policy.getPolicyUuid(), vendor.getUuid(), null);
			}
			if (bocloudResult.isSuccess()) {
				vpnPolicyRepository.remove(id, context.getTarget());
				return new BocloudResult<>(true, "删除策略成功");
			} else {
				return new BocloudResult<>(false, bocloudResult.getMessage());
			}
		} catch (Exception e) {
			logger.error("modify network fail:", e);
			return new BocloudResult<>(false, "删除策略失败");
		}
	}

	@Override
	public BocloudResult<VpnPolicy> detail(Long id) {
		String path = VpnPolicy.class.getSimpleName() + "_" + id;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			VpnPolicy policy = vpnPolicyRepository.query(id);
			if (null == policy) {
				logger.warn("network data not exist");
				return new BocloudResult<>(false, "数据不存在");
			}
			if (!org.springframework.util.StringUtils.isEmpty(policy.getTenantUuid())) {
				OSTenant osTenant = osTenantRepository.getByTenantUuid(policy.getTenantUuid(), policy.getVendorId());
				if (null != osTenant) {
					policy.setOsTenantName(osTenant.getName());
				}
			}
			return new BocloudResult<>(true, policy, "查询详情成功");
		} catch (Exception e) {
			logger.error("modify network fail:", e);
			return new BocloudResult<>(false, "查询详情失败");
		}
	}

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

}
