package com.bocloud.ims.service.check;

import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.Sign;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.MapTools;
import com.bocloud.ims.interfaces.check.ResourceCheckService;
import com.bocloud.ims.repository.resource.*;
import com.bocloud.ims.repository.resource.f5.F5BiVirtualServerRepository;
import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 租户资源删除校验service实现
 *
 * @author wangyu
 * @version 1.0
 * @since 2018年1月15日
 */
@Service("resourceCheckService")
public class ResourceCheckServiceImpl implements ResourceCheckService {

    private static Logger logger = LoggerFactory.getLogger(ResourceCheckServiceImpl.class);
    @Autowired
    private CloudServerRepository cloudServerRepository;
    @Autowired
    private FirewallRepository firewallRepository;
    @Autowired
    private FirewallPolicyRepository firewallPolicyRepository;
    @Autowired
    private FirewallRuleRepository firewallRuleRepository;
    @Autowired
    private FloatingIpRepository floatingIpRepository;
    @Autowired
    private ImageRepository imageRepository;
    @Autowired
    private KeypairRepository keypairRepository;
    @Autowired
    private LbMemberRepository lbMemberRepository;
    @Autowired
    private LoadBalancerRepository loadBalancerRepository;
    @Autowired
    private ResourceRepository resourceRepository;
    @Autowired
    private RouterRepository routerRepository;
    @Autowired
    private SecurityGroupRepository securityGroupRepository;
    @Autowired
    private SecurityGroupRuleRepository securityGroupRuleRepository;
    @Autowired
    private SnapshotRepository snapshotRepository;
    @Autowired
    private TenantNetworkRepository tenantNetworkRepository;
    @Autowired
    private VolumeRepository volumeRepository;
    @Autowired
    private F5BiVirtualServerRepository f5BiVirtualServerRepository;

    @Override
    public BocloudResult check(Long target, String category) {
        if ("TENANT".equalsIgnoreCase(category)) {
            return this.tenantCheck(target);
        } else {
            return this.projectCheck(target);
        }
    }

    /**
     * 校验租户下资源
     *
     * @param tenantId
     * @return
     */
    private BocloudResult tenantCheck(Long tenantId) {
        try {
            boolean flag = false;
            flag = cloudServerRepository.tenantCheck(tenantId, 0L, 0L);
            if (flag) {
                return new BocloudResult(false, "该租户下存在正在使用的云主机，请先删除");
            }
            flag = firewallRepository.tenantCheck(tenantId, 0L, 0L);
            if (flag) {
                return new BocloudResult(false, "该租户下存在正在使用的防火墙，请先删除");
            }
            flag = firewallPolicyRepository.tenantCheck(tenantId, 0L, 0L);
            if (flag) {
                return new BocloudResult(false, "该租户下存在正在使用的防火墙策略，请先删除");
            }
            flag = firewallRuleRepository.tenantCheck(tenantId, 0L, 0L);
            if (flag) {
                return new BocloudResult(false, "该租户下存在正在使用的防火墙规格，请先删除");
            }
            flag = floatingIpRepository.tenantCheck(tenantId, 0L, 0L);
            if (flag) {
                return new BocloudResult(false, "该租户下存在正在使用的浮动IP，请先删除");
            }
            flag = imageRepository.tenantCheck(tenantId, 0L, 0L);
            if (flag) {
                return new BocloudResult(false, "该租户下存在正在使用的云镜像，请先删除");
            }
            flag = keypairRepository.tenantCheck(tenantId, 0L, 0L);
            if (flag) {
                return new BocloudResult(false, "该租户下存在正在使用的密钥，请先删除");
            }
            flag = lbMemberRepository.tenantCheck(tenantId, 0L, 0L);
            if (flag) {
                return new BocloudResult(false, "该租户下存在正在使用的负载均衡器成员，请先删除");
            }
            flag = loadBalancerRepository.tenantCheck(tenantId, 0L, 0L);
            if (flag) {
                return new BocloudResult(false, "该租户下存在正在使用的负载均衡器，请先删除");
            }
            flag = resourceRepository.tenantCheck(tenantId, 0L, 0L);
            if (flag) {
                return new BocloudResult(false, "该租户下存在正在使用的云主机或宿主机，请先删除");
            }
            flag = routerRepository.tenantCheck(tenantId, 0L, 0L);
            if (flag) {
                return new BocloudResult(false, "该租户下存在正在使用的路由，请先删除");
            }
            flag = securityGroupRepository.tenantCheck(tenantId, 0L, 0L);
            if (flag) {
                return new BocloudResult(false, "该租户下存在正在使用的安全组，请先删除");
            }
            flag = securityGroupRuleRepository.tenantCheck(tenantId, 0L, 0L);
            if (flag) {
                return new BocloudResult(false, "该租户下存在正在使用的安全组规则，请先删除");
            }
            flag = snapshotRepository.tenantCheck(tenantId, 0L, 0L);
            if (flag) {
                return new BocloudResult(false, "该租户下存在正在使用的云快照，请先删除");
            }
            flag = tenantNetworkRepository.tenantCheck(tenantId);
            if (flag) {
                return new BocloudResult(false, "该租户下存在正在使用的云网络，请先删除");
            }
            flag = volumeRepository.tenantCheck(tenantId, 0L, 0L);
            if (flag) {
                return new BocloudResult(false, "该租户下存在正在使用的云硬盘，请先删除");
            }
            return new BocloudResult(true, "校验通过");
        } catch (Exception e) {
            logger.error("Get error message:", e);
            return new BocloudResult(false, "校验失败");
        }
    }

    /**
     * 校验项目下资源
     *
     * @param projectId
     * @return
     */
    private BocloudResult projectCheck(Long projectId) {
        try {
            boolean flag = false;
            flag = cloudServerRepository.tenantCheck(0L, projectId, 0L);
            if (flag) {
                return new BocloudResult(false, "该项目下存在正在使用的云主机，请先删除");
            }
            flag = firewallRepository.tenantCheck(0L, projectId, 0L);
            if (flag) {
                return new BocloudResult(false, "该项目下存在正在使用的防火墙，请先删除");
            }
            flag = firewallPolicyRepository.tenantCheck(0L, projectId, 0L);
            if (flag) {
                return new BocloudResult(false, "该项目下存在正在使用的防火墙策略，请先删除");
            }
            flag = firewallRuleRepository.tenantCheck(0L, projectId, 0L);
            if (flag) {
                return new BocloudResult(false, "该项目下存在正在使用的防火墙规格，请先删除");
            }
            flag = floatingIpRepository.tenantCheck(0L, projectId, 0L);
            if (flag) {
                return new BocloudResult(false, "该项目下存在正在使用的浮动IP，请先删除");
            }
            flag = imageRepository.tenantCheck(0L, projectId, 0L);
            if (flag) {
                return new BocloudResult(false, "该项目下存在正在使用的云镜像，请先删除");
            }
            flag = keypairRepository.tenantCheck(0L, projectId, 0L);
            if (flag) {
                return new BocloudResult(false, "该项目下存在正在使用的密钥，请先删除");
            }
            flag = lbMemberRepository.tenantCheck(0L, projectId, 0L);
            if (flag) {
                return new BocloudResult(false, "该项目下存在正在使用的负载均衡器成员，请先删除");
            }
            flag = loadBalancerRepository.tenantCheck(0L, projectId, 0L);
            if (flag) {
                return new BocloudResult(false, "该项目下存在正在使用的负载均衡器，请先删除");
            }
            flag = resourceRepository.tenantCheck(0L, projectId, 0L);
            if (flag) {
                return new BocloudResult(false, "该项目下存在正在使用的云主机或宿主机，请先删除");
            }
            flag = routerRepository.tenantCheck(0L, projectId, 0L);
            if (flag) {
                return new BocloudResult(false, "该项目下存在正在使用的路由，请先删除");
            }
            flag = securityGroupRepository.tenantCheck(0L, projectId, 0L);
            if (flag) {
                return new BocloudResult(false, "该项目下存在正在使用的安全组，请先删除");
            }
            flag = securityGroupRuleRepository.tenantCheck(0L, projectId, 0L);
            if (flag) {
                return new BocloudResult(false, "该项目下存在正在使用的安全组规则，请先删除");
            }
            flag = snapshotRepository.tenantCheck(0L, projectId, 0L);
            if (flag) {
                return new BocloudResult(false, "该项目下存在正在使用的云快照，请先删除");
            }
            flag = volumeRepository.tenantCheck(0L, projectId, 0L);
            if (flag) {
                return new BocloudResult(false, "该项目下存在正在使用的云硬盘，请先删除");
            }
            flag = f5BiVirtualServerRepository.tenantCheck(projectId);
            if (flag) {
                return new BocloudResult(false, "该项目下存在正在使用的F5资源，请先删除");
            }
            return new BocloudResult(true, "校验通过");
        } catch (Exception e) {
            logger.error("Get error message:", e);
            return new BocloudResult(false, "校验失败");
        }
    }

    @Override
    public BocloudResult checkRes(Long tenantId, Long projectId, Long userId) {
        if (null != projectId && 0L != projectId) {
            return this.check(tenantId, projectId, userId);
        } else {
            return this.check(tenantId, userId);
        }
    }

    /**
     * 校验指定云平台在租户下是否有资源
     *
     * @param vendorId
     * @param tenantId
     * @return
     */
    @Override
    public BocloudResult vendorCheck(String groupName, Long vendorId, Long tenantId) {
        try {
            List<Param> params = new ArrayList<>();
            params.add(new Param(MapTools.simpleMap(Common.VENDORID, vendorId), Sign.EQ));
            params.add(new Param(MapTools.simpleMap(Common.TENANTID, tenantId), Sign.EQ));
            boolean flag = false;
            flag = cloudServerRepository.count(params) > 0;
            if (flag) {
                return new BocloudResult(false, "要移除的资源池【" + groupName + "】所在云平台有正在使用的云主机，请先删除");
            }
            flag = firewallRepository.count(params) > 0;
            if (flag) {
                return new BocloudResult(false, "要移除的资源池【" + groupName + "】所在云平台有正在使用的防火墙，请先删除");
            }
            flag = firewallPolicyRepository.count(params) > 0;
            if (flag) {
                return new BocloudResult(false, "要移除的资源池【" + groupName + "】所在云平台有正在使用的防火墙策略，请先删除");
            }
            flag = firewallRuleRepository.count(params) > 0;
            if (flag) {
                return new BocloudResult(false, "要移除的资源池【" + groupName + "】所在云平台有正在使用的防火墙规格，请先删除");
            }
            flag = floatingIpRepository.count(params, "") > 0;
            if (flag) {
                return new BocloudResult(false, "要移除的资源池【" + groupName + "】所在云平台有正在使用的浮动IP，请先删除");
            }
            flag = imageRepository.count(params, "") > 0;
            if (flag) {
                return new BocloudResult(false, "要移除的资源池【" + groupName + "】所在云平台有正在使用的云镜像，请先删除");
            }
            flag = keypairRepository.count(params) > 0;
            if (flag) {
                return new BocloudResult(false, "要移除的资源池【" + groupName + "】所在云平台有正在使用的密钥，请先删除");
            }
            flag = lbMemberRepository.count(params) > 0;
            if (flag) {
                return new BocloudResult(false, "要移除的资源池【" + groupName + "】所在云平台有正在使用的负载均衡器成员，请先删除");
            }
            flag = loadBalancerRepository.count(params) > 0;
            if (flag) {
                return new BocloudResult(false, "要移除的资源池【" + groupName + "】所在云平台有正在使用的负载均衡器，请先删除");
            }
            flag = routerRepository.count(params) > 0;
            if (flag) {
                return new BocloudResult(false, "要移除的资源池【" + groupName + "】所在云平台有正在使用的路由，请先删除");
            }
            flag = securityGroupRepository.count(params) > 0;
            if (flag) {
                return new BocloudResult(false, "要移除的资源池【" + groupName + "】所在云平台有正在使用的安全组，请先删除");
            }
            flag = securityGroupRuleRepository.count(params) > 0;
            if (flag) {
                return new BocloudResult(false, "要移除的资源池【" + groupName + "】所在云平台有正在使用的安全组规则，请先删除");
            }
            flag = snapshotRepository.count(params) > 0;
            if (flag) {
                return new BocloudResult(false, "要移除的资源池【" + groupName + "】所在云平台有正在使用的云快照，请先删除");
            }
            flag = tenantNetworkRepository.tenantCheck(tenantId, vendorId);
            if (flag) {
                return new BocloudResult(false, "要移除的资源池【" + groupName + "】所在云平台有正在使用的云网络，请先删除");
            }
            flag = volumeRepository.count(params) > 0;
            if (flag) {
                return new BocloudResult(false, "要移除的资源池【" + groupName + "】所在云平台有正在使用的云硬盘，请先删除");
            }
            return new BocloudResult(true, "校验通过");
        } catch (Exception e) {
            logger.error("Get error message:", e);
            return new BocloudResult(false, "校验失败");
        }
    }

    /**
     * 租户下用户资源校验
     *
     * @param tenantId
     * @param userId
     * @return
     */
    private BocloudResult check(Long tenantId, Long userId) {
        try {
            List<Param> list = Lists.newArrayList();
            int count = cloudServerRepository.count(list, null, tenantId, null, null);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在租户下存在正在使用的云主机，请先删除");
            }
            count = firewallRepository.count(list, userId, tenantId, null);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在租户下存在正在使用的防火墙，请先删除");
            }
            count = firewallPolicyRepository.count(list, userId, tenantId, null);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在租户下存在正在使用的防火墙策略，请先删除");
            }
            count = firewallRuleRepository.count(list, userId, tenantId, null);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在租户下存在正在使用的防火墙规则，请先删除");
            }
            count = floatingIpRepository.count(list, tenantId, null);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在租户下存在正在使用的浮动IP，请先删除");
            }
            count = imageRepository.count(list, tenantId, null);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在租户下存在正在使用的云镜像，请先删除");
            }
            boolean flag = keypairRepository.tenantCheck(tenantId, 0L, userId);
            if (flag) {
                return new BocloudResult(false, "该用户所在租户下存在正在使用的密钥，请先删除");
            }
            count = loadBalancerRepository.count(list, tenantId, null);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在租户下存在正在使用的负载均衡器，请先删除");
            }
            count = routerRepository.count(list, tenantId, null);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在租户下存在正在使用的路由，请先删除");
            }
            count = securityGroupRepository.count(list, userId, tenantId, null);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在租户下存在正在使用的安全组，请先删除");
            }
            count = snapshotRepository.count(list, tenantId, null);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在租户下存在正在使用的云快照，请先删除");
            }
            count = volumeRepository.count(list, tenantId, null);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在租户下存在正在使用的云硬盘，请先删除");
            }
            return new BocloudResult(true, "校验通过");
        } catch (Exception e) {
            logger.error("Get error message:", e);
            return new BocloudResult(false, "校验失败");
        }
    }

    /**
     * 项目下用户资源校验
     *
     * @param tenantId
     * @param projectId
     * @param userId
     * @return
     */
    private BocloudResult check(Long tenantId, Long projectId, Long userId) {
        try {
            List<Param> list = Lists.newArrayList();
            List<Long> projectIds = new ArrayList<>();
            projectIds.add(projectId);
            int count = cloudServerRepository.count(list, null, tenantId, projectIds, null);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在旧项目下存在正在使用的云主机，请先删除");
            }
            count = firewallRepository.count(list, userId, tenantId, projectId);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在旧项目下存在正在使用的防火墙，请先删除");
            }
            count = firewallPolicyRepository.count(list, userId, tenantId, projectId);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在旧项目下存在正在使用的防火墙策略，请先删除");
            }
            count = firewallRuleRepository.count(list, userId, tenantId, projectId);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在旧项目下存在正在使用的防火墙规格，请先删除");
            }
            count = floatingIpRepository.count(list, tenantId, projectIds);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在旧项目下存在正在使用的浮动IP，请先删除");
            }
            count = imageRepository.count(list, tenantId, projectIds);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在旧项目下存在正在使用的云镜像，请先删除");
            }
            count = loadBalancerRepository.count(list, tenantId, projectIds);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在旧项目下存在正在使用的负载均衡器，请先删除");
            }
            count = routerRepository.count(list, tenantId, projectIds);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在旧项目下存在正在使用的路由，请先删除");
            }
            count = securityGroupRepository.count(list, userId, tenantId, projectId);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在旧项目下存在正在使用的安全组，请先删除");
            }
            count = snapshotRepository.count(list, tenantId, projectIds);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在旧项目下存在正在使用的云快照，请先删除");
            }
            count = volumeRepository.count(list, tenantId, projectIds);
            if (count > 0) {
                return new BocloudResult(false, "该用户所在旧项目下存在正在使用的云硬盘，请先删除");
            }
            return new BocloudResult(true, "校验通过");
        } catch (Exception e) {
            logger.error("Get error message:", e);
            return new BocloudResult(false, "校验失败");
        }
    }
}
