package com.bocloud.ims.repository.resource;

import com.bocloud.common.enums.BaseStatus;
import com.bocloud.common.exception.BoCloudDBException;
import com.bocloud.common.model.Pager;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.SimpleBean;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.IDFactory;
import com.bocloud.common.utils.ListTool;
import com.bocloud.common.utils.MapTools;
import com.bocloud.database.core.intf.impl.BasicGenericDao;
import com.bocloud.database.utils.QueryBuilder;
import com.bocloud.ims.entity.common.MathUtils;
import com.bocloud.ims.entity.resource.*;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.*;

/**
 * 云平台数据访问
 *
 * @author wangyu
 * @version 1.0
 * @since 2020年5月15日
 */
@Repository("cloudVendorRepository")
public class CloudVendorRepository extends BasicGenericDao<CloudVendor, Long> {

    public CloudVendorRepository(JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate npJdbcTemplate) {
        super(jdbcTemplate, npJdbcTemplate);
    }

    @Override
    public void save(CloudVendor vendor) throws BoCloudDBException {
        vendor.setGuid(IDFactory.instance().uuid());
        super.save(vendor);
    }

    public boolean delete(Long id, Long userId) {
        String sql = "update cloud_vendor set is_deleted = 1, gmt_modify = :gmtModify, mender_id = :menderId where id = :id";
        Map<String, Object> params = MapTools.simpleMap("id", id);
        params.put("gmtModify", new Date());
        params.put("menderId", userId);
        return this.execute(sql, params) > 0;
    }

    public boolean lock(Long id, Long userId) {
        String sql = "update cloud_vendor set is_locked = 1, status = :status, gmt_modify = :gmtModify, mender_id = :menderId where id = :id and is_deleted = 0";
        Map<String, Object> params = MapTools.simpleMap("id", id);
        params.put("gmtModify", new Date());
        params.put("menderId", userId);
        params.put("status", BaseStatus.ABNORMAL.name());
        return this.execute(sql, params) > 0;
    }

    public List<Map<String, Object>> vendorStatusStats() {
        String sql = "SELECT sum(status = 'NORMAL' ) as normal,sum(status = 'ABNORMAL' ) as abnormal FROM cloud_vendor WHERE type in ('OPENSTACK','VMWARE','FUSIONCLOUD','HMC','MANAGEONE','KUBERNETES','TIANYI','HUAWEI','H3C','ALIYUN','SMARTX','EASYSTACK') and is_deleted = 0";
        return this.list(sql);
    }
    
    public List<CloudVendor> vendorStatusList() {
        String sql = "SELECT * FROM cloud_vendor WHERE type in ('OPENSTACK','AWS','AZURE','HMC','QCLOUD','TENCENT', 'VMWARE','FUSIONCLOUD','HMC','MANAGEONE','KUBERNETES','TIANYI','HUAWEI','H3C','ALIYUN','SMARTX','EASYSTACK','SANGFOR') and is_deleted = 0";
        Map<String, Object> params = new HashMap<>();
        return this.list(CloudVendor.class, sql, params);
    }

    public boolean active(Long id, Long userId) {
        String sql = "update cloud_vendor set is_locked = 0, status = :status, gmt_modify = :gmtModify, mender_id = :menderId  where id = :id and is_deleted = 0";
        Map<String, Object> params = MapTools.simpleMap("id", id);
        params.put("gmtModify", new Date());
        params.put("menderId", userId);
        params.put("status", BaseStatus.NORMAL.name());
        return this.execute(sql, params) > 0;
    }

    public CloudVendor getByName(String name) {
        String sql = "select * from cloud_vendor where name = :name and is_deleted = 0";
        Map<String, Object> params = MapTools.simpleMap("name", name);
        List<CloudVendor> list = this.list(CloudVendor.class, sql, params);
        if (list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    public List<CloudVendor> list(int page, int rows, List<Param> params, Map<String, String> sorter,
                                  List<Long> vendorIds) {
        String sql = "SELECT " + "a.*, b. NAME env_name,c. NAME dc_name,d.instance,d. ONLINE,d.offline,d.host_count,"
                + "d.data_store_count,d.template_count,d.cluster_count,d.image_count,d.cpu_count,"
                + "d.mon_count,d.osd_count,d.mds_count,d.cpu_total,d.cpu_used,d.cpu_unused,d.mem_total,"
                + "d.mem_used,d.mem_unused,d.disk_total,d.disk_used,d.disk_unused,d.tenant_count,"
                + "d.network_count,d.vs_count,d.pool_count,d.node_count,d.profile_count,d.monitor_count,"
                + "d.vpc_count,d.lpar_count,d.vios_count,d.mdisk_count,d.flash_copy_count,d.fabric_count,d.zone_count,"
                + "d.ns_count,d.pod_count,d.service_count,d.deployment_count,d.alias_count,"
                + "d.access_path_count AS access_path_count,d.edge_cluster_count,d.group_count,d.transport_zone_count,"
                + "d.firewall_count,d.router_count,d.switch_count,d.object_user_count,d.object_bucket_count,"
                + "d.object_router_count,d.desktop_pools,d.farms,d.sessions,d.users,d.vcenters,"
                + "d.file_user_count , d.file_client_count , d.snapshot_count, d.file_system_count, d.logic_port_count,"
                + "d.vas_count, d.app_count, d.session_count, d.db_count " + "FROM cloud_vendor a "
                + "LEFT JOIN environment b ON a.env_id = b.id " + "LEFT JOIN data_center c ON c.id = a.dc_id "
                + "LEFT JOIN cloud_vendor_statistics d ON d.vendor_id = a.id " + "WHERE " + "a.is_deleted = 0 "
                + "AND a.type IS NOT NULL";
        Map<String, Object> paramMap = QueryBuilder.getParam(params);
        if (!ListTool.isEmpty(vendorIds)) {
            sql += " and a.id in (:vendorIds) ";
            paramMap.put("vendorIds", vendorIds);
        }
        sql = QueryBuilder.buildRaw(sql, new Pager(page, rows, params, sorter), "a");
        return this.list(CloudVendor.class, sql, paramMap);
    }

    public List<CloudVendor> list(int page, int rows, List<Param> params, Map<String, String> sorter) {
        String sql = "SELECT "
                + "a.*, b. NAME env_name,c. NAME dc_name,d.instance,d. ONLINE,d.offline,d.host_count,d.data_store_count,d.template_count,d.cluster_count,d.image_count,d.cpu_count,d.mon_count,d.osd_count,d.mds_count,d.cpu_total,d.cpu_used,d.cpu_unused,d.mem_total,d.mem_used,d.mem_unused,d.disk_total,d.disk_used,d.disk_unused,d.tenant_count,d.network_count,d.vs_count,d.pool_count,d.node_count,d.profile_count,d.monitor_count,d.vpc_count,d.lpar_count,d.vios_count,d.mdisk_count,d.flash_copy_count,d.fabric_count,d.zone_count,d.ns_count,d.pod_count,d.service_count,d.deployment_count,d.alias_count,d.access_path_count AS access_path_count,d.edge_cluster_count,d.group_count,d.transport_zone_count,d.firewall_count,d.router_count,d.switch_count,d.object_user_count,d.object_bucket_count,d.object_router_count,d.desktop_pools,d.farms,d.sessions,d.users,d.vcenters"
                + " , d.file_user_count , d.file_client_count , d.snapshot_count, d.file_system_count, d.logic_port_count, d.vas_count "
                + "FROM " + "cloud_vendor a " + "LEFT JOIN environment b ON a.env_id = b.id "
                + "LEFT JOIN data_center c ON c.id = a.dc_id "
                + "LEFT JOIN cloud_vendor_statistics d ON d.vendor_id = a.id " + "WHERE " + "a.is_deleted = 0 "
                + "AND a.type IS NOT NULL";
        Map<String, Object> paramMap = QueryBuilder.getParam(params);
        sql = QueryBuilder.buildRaw(sql, new Pager(page, rows, params, sorter), "a");
        return this.list(CloudVendor.class, sql, paramMap);
    }

    public List<SimpleBean> list(List<Param> params, Map<String, String> sorter, List<Long> vendorIds) {
        String sql = "select a.id,a.name,a.uuid from cloud_vendor a where a.is_deleted = 0";
        Map<String, Object> paramMap = QueryBuilder.getParam(params);
        if (!ListTool.isEmpty(vendorIds)) {
            sql += " and a.id in (:vendorIds) ";
            paramMap.put("vendorIds", vendorIds);
        }
        sql = QueryBuilder.build(sql, new Pager(1, Integer.MAX_VALUE, params, sorter), "a");
        List<CloudVendor> vendors = this.list(CloudVendor.class, sql, paramMap);
        List<SimpleBean> beans = new ArrayList<>();
        for (CloudVendor vendor : vendors) {
            SimpleBean bean = new SimpleBean(vendor.getId(), vendor.getName());
            bean.setUuid(vendor.getUuid());
            bean.setValue(vendor.getType());
            beans.add(bean);
        }
        return beans;
    }

    public List<SimpleBean> list(List<Param> params, Map<String, String> sorter) {
        String sql = "select a.id,a.name,a.uuid from cloud_vendor a where a.is_deleted = 0";
        Map<String, Object> paramMap = QueryBuilder.getParam(params);
        sql = QueryBuilder.build(sql, new Pager(1, Integer.MAX_VALUE, params, sorter), "a");
        List<CloudVendor> vendors = this.list(CloudVendor.class, sql, paramMap);
        List<SimpleBean> beans = new ArrayList<>();
        for (CloudVendor vendor : vendors) {
            SimpleBean bean = new SimpleBean(vendor.getId(), vendor.getName());
            bean.setUuid(vendor.getUuid());
            bean.setValue(vendor.getType());
            beans.add(bean);
        }
        return beans;
    }

    public int count(List<Param> params, List<Long> vendorIds) {
        String sql = "select count(1) from cloud_vendor a where a.is_deleted = 0 and a.type is not null";
        Map<String, Object> paramMap = QueryBuilder.getParam(params);
        if (!ListTool.isEmpty(vendorIds)) {
            sql += " and a.id in (:vendorIds) ";
            paramMap.put("vendorIds", vendorIds);
        }
        sql = QueryBuilder.build(sql, params, null, "a");
        return this.countQuery(sql, paramMap).intValue();
    }

    public int count(List<Param> params) {
        String sql = "select count(1) from cloud_vendor a where a.is_deleted = 0 and a.type is not null";
        Map<String, Object> paramMap = QueryBuilder.getParam(params);
        sql = QueryBuilder.build(sql, params, null, "a");
        return this.countQuery(sql, paramMap).intValue();
    }

    public CloudVendor query(Long id) {
        String sql = "select a.*,b.name env_name,c.name dc_name,d.instance,d.online,d.offline,d.host_count,d.data_store_count,d.template_count,d.cluster_count,d.image_count,d.cpu_count,d.mon_count,d.osd_count,d.mds_count,d.cpu_total,d.cpu_used,d.cpu_unused,d.mem_total,d.mem_used,d.mem_unused,d.disk_total,d.disk_used,d.disk_unused,d.tenant_count,d.network_count,d.vs_count,d.pool_count,d.node_count,d.profile_count,d.monitor_count,d.vpc_count,d.lpar_count,d.vios_count,d.mdisk_count,d.flash_copy_count,d.fabric_count,d.zone_count,d.ns_count,d.pod_count,d.service_count,d.deployment_count,d.alias_count, d.access_path_count as access_path_count,d.edge_cluster_count,d.group_count,d.transport_zone_count,d.firewall_count,d.router_count,d.switch_count,d.desktop_pools,d.farms,d.sessions,d.users,d.vcenters from cloud_vendor a left join environment b on a.env_id = b.id left join data_center c on c.id = a.dc_id left join cloud_vendor_statistics d on d.vendor_id = a.id where a.is_deleted = 0 and a.id = :id";
        Map<String, Object> paramMap = MapTools.simpleMap("id", id);
        List<CloudVendor> list = this.list(CloudVendor.class, sql, paramMap);
        if (list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    public CloudVendor query(String uuid) {
        String sql = "select a.*,b.name env_name from cloud_vendor a left join environment b on a.env_id = b.id where a.uuid =:uuid";
        Map<String, Object> paramMap = MapTools.simpleMap("uuid", uuid);
        List<CloudVendor> list = this.list(CloudVendor.class, sql, paramMap);
        if (list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    /**
     * @since 2018-12-28 modify by sxp Xen平台的登陆账户在服务器表中
     */

    public List<CloudVendor> listAll() {
        String sql = "select * from cloud_vendor where is_deleted = 0";
        List<CloudVendor> vendors = this.list(CloudVendor.class, sql);

        StringBuilder sb = new StringBuilder(200);
        sb.append("select a.id, a.manage_ip, b.username, b.password ");
        sb.append("  from server a ");
        sb.append(" inner join server_config b on b.server_id = a.id ");
        sb.append(" where a.is_deleted = 0 ");
        sb.append("   and a.vendor_id = :vendorId ");
        sql = sb.toString();

        Map<String, Object> paramMap = new HashMap<>(1);
        List<Map<String, Object>> list;
        List<Server> servers;
        ServerConfig config;
        Server server;

        for (CloudVendor vendor : vendors) {
            paramMap.put(Common.VENDORID, vendor.getId());
            list = this.list(sql, paramMap);
            if (list == null || list.isEmpty()) {
                continue;
            }
            servers = new ArrayList<>(list.size());

            for (Map<String, Object> item : list) {
                server = new Server();
                server.setId(MathUtils.castToLongClass(item.get("id")));
                server.setManageIp(String.valueOf(item.get("manage_ip")));

                config = new ServerConfig();
                config.setUsername(String.valueOf(item.get("username")));
                config.setPassword(String.valueOf(item.get("password")));

                server.setConfig(config);
                servers.add(server);
            }

            vendor.setServers(servers);
        }

        return vendors;
    }

    public CloudVendor getByAddress(String address) {
        String sql = "select * from cloud_vendor where authentication like :address and is_deleted = 0";
        Map<String, Object> params = MapTools.simpleMap("address", "%" + address + "%");
        List<CloudVendor> list = this.list(CloudVendor.class, sql, params);
        if (list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    public CloudVendor getByAk(String ak, String sk) {
        String sql = "select * from cloud_vendor where authentication like :ak and is_deleted = 0 and authentication like :sk ";
        Map<String, Object> params = MapTools.simpleMap("ak", "%" + ak + "%");
        params.put("sk", "%" + sk + "%");
        List<CloudVendor> list = this.list(CloudVendor.class, sql, params);
        if (list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    public List<CloudVendor> listAuthProvider(List<String> types, Long tenantId) {
        String sql = "select a.*,b.name env_name from cloud_vendor a left join environment b on a.env_id = b.id where a.is_deleted = 0 and a.id in (select b.vendor_id from tenant_provider b where b.tenant_id = :tenantId )";
        Map<String, Object> params = MapTools.simpleMap("tenantId", tenantId);
        if (!ListTool.isEmpty(types)) {
            sql += " and a.type in (:types)";
            params.put("types", types);
        }
        return this.list(CloudVendor.class, sql, params);
    }

    public List<CloudVendor> list(List<Param> params) {
        String sql = "select a.*,b.name env_name from cloud_vendor a left join environment b on a.env_id = b.id where a.is_deleted = 0";
        sql = QueryBuilder.build(sql, new Pager(1, Integer.MAX_VALUE, params, new HashMap<>(8)), "a");
        Map<String, Object> paramMap = QueryBuilder.getParam(params);
        return this.list(CloudVendor.class, sql, paramMap);
    }

    public List<CloudVendor> list(List<Param> params, Long vdcId) {
        String sql = "select a.*,b.name env_name from cloud_vendor a left join environment b on a.env_id = b.id LEFT JOIN vdc v ON a.id=v.vendor_id where a.is_deleted = 0";
        sql = QueryBuilder.build(sql, new Pager(1, Integer.MAX_VALUE, params, new HashMap<>(8)), "a");
        Map<String, Object> paramMap = QueryBuilder.getParam(params);
        if (null != vdcId) {
            sql += " and v.id = :vdcId ";
            paramMap.put("vdcId", vdcId);
        }
        return this.list(CloudVendor.class, sql, paramMap);
    }

    public List<CloudVendor> listByType(String type) {
        String sql = "select a.*,b.name env_name from cloud_vendor a left join environment b on a.env_id = b.id where a.is_deleted = 0 ";
        Map<String, Object> paramMap = Maps.newHashMap();
        if (!StringUtils.isEmpty(type)) {
            sql += " and a.type = :type";
            paramMap.put("type", type);
        }
        return this.list(CloudVendor.class, sql, paramMap);
    }

    public List<CloudVendor> listByType(String type, Long vendorId) {
        String sql = "select a.*,b.name env_name from cloud_vendor a left join environment b on a.env_id = b.id where a.is_deleted = 0 ";
        Map<String, Object> paramMap = Maps.newHashMap();
        if (!StringUtils.isEmpty(type)) {
            sql += " and a.type = :type";
            paramMap.put("type", type);
        }
        if (null != vendorId && 0 != vendorId) {
            sql += " and a.id = :vendorId ";
            paramMap.put("vendorId", vendorId);
        }
        return this.list(CloudVendor.class, sql, paramMap);
    }


    public CloudVendor listById(Long vendorId) {
        String sql = "select a.*,b.name env_name from cloud_vendor a left join environment b on a.env_id = b.id where a.is_deleted = 0 ";
        Map<String, Object> paramMap = Maps.newHashMap();
        if (null != vendorId && 0 != vendorId) {
            sql += " and a.id = :vendorId ";
            paramMap.put("vendorId", vendorId);
        }
        List<CloudVendor> list = this.list(CloudVendor.class, sql, paramMap);
        return list.get(0);
    }

    /**
     * 查询所属环境下的云平台
     *
     * @param envId
     * @return
     * @throws Exception
     */

    public List<CloudVendor> listByEnvId(Long envId) {
        String sql = "select a.*,b.name env_name from cloud_vendor a left join environment b on a.env_id = b.id where a.is_deleted = 0 and a.env_id = :envId";
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("envId", envId);
        return this.list(CloudVendor.class, sql, paramMap);
    }

    public List<CloudVendor> listByPool(String category, Boolean isPublic) {
        String sql = "select a.* from cloud_vendor a where a.is_deleted = 0 ";
        if (null != isPublic) {
            sql += " and a.is_public = " + isPublic;
        }
        if (null != category && "computepool".equals(category)) {
            // 解决无法创建FusionSphere资源池的问题 sxp:2022/8/25
            sql += " and a.type in ('OPENSTACK','VMWARE','ALIYUN','JDCLOUD','H3C','FUSIONCLOUD','TENCENT','HUAWEI', 'HCSO','AZURE','KINGCLOUD','AWS','QCLOUD','TCE','MANAGEONE','TIANYI','SMARTX','EASYSTACK','FUSIONSPHERE','SANGFOR') ";
        }
        if (null != category && "networkpool".equals(category)) {
            sql += " and a.type in ('OPENSTACK' ,'VMWARE', 'FUSIONCLOUD', 'MANAGEONE','EASYSTACK') ";
        }

        return this.list(CloudVendor.class, sql, null);
    }

    public boolean isOpenAlarm(Long id) {
        String sql = "select a.* from cloud_vendor a where a.is_deleted = 0 and a.id =:id and is_alarm = 0";
        Map<String, Object> paramMap = MapTools.simpleMap("id", id);
        List<CloudVendor> list = this.list(CloudVendor.class, sql, paramMap);
        return list.isEmpty();
    }

    public List<CloudVendor> listByTypes(List<String> types, Long dcId) {
        String sql = "SELECT "
                + "a.*, b. name env_name,c. name dc_name,d.instance,d. ONLINE,d.offline,d.host_count,d.data_store_count,d.template_count,d.cluster_count,d.image_count,d.cpu_count,d.mon_count,d.osd_count,d.mds_count,d.cpu_total,d.cpu_used,d.cpu_unused,d.mem_total,d.mem_used,d.mem_unused,d.disk_total,d.disk_used,d.disk_unused,d.tenant_count,d.network_count,d.vs_count,d.pool_count,d.node_count,d.profile_count,d.monitor_count,d.vpc_count,d.lpar_count,d.vios_count,d.mdisk_count,d.flash_copy_count,d.fabric_count,d.zone_count,d.ns_count,d.pod_count,d.service_count,d.deployment_count,d.alias_count,d.access_path_count AS access_path_count,d.edge_cluster_count,d.group_count,d.transport_zone_count,d.firewall_count,d.router_count,d.switch_count,d.object_user_count,d.object_bucket_count,d.object_router_count "
                + "FROM " + "cloud_vendor a " + "LEFT JOIN environment b ON a.env_id = b.id "
                + "LEFT JOIN data_center c ON c.id = a.dc_id "
                + "LEFT JOIN cloud_vendor_statistics d ON d.vendor_id = a.id " + "WHERE " + "a.is_deleted = 0 ";
        Map<String, Object> paramMap = Maps.newHashMap();
        if (!ListTool.isEmpty(types)) {
            sql += " and a.type in (:types)";
            paramMap.put("types", types);
        }
        if (null != dcId) {
            sql += " and a.dc_id = :dcId ";
            paramMap.put("dcId", dcId);
        }
        return this.list(CloudVendor.class, sql, paramMap);
    }


    public List<CloudVendor> listSimpleTypes(List<String> types) {
        String sql = "SELECT a.* FROM cloud_vendor a "
                + " WHERE a.is_deleted = 0 ";
        Map<String, Object> paramMap = Maps.newHashMap();
        if (!ListTool.isEmpty(types)) {
            sql += " and a.type in (:types)";
            paramMap.put("types", types);
        }
        return this.list(CloudVendor.class, sql, paramMap);
    }

    /**
     * 根据数据中心id查询
     *
     * @param dcId
     * @return
     * @throws Exception
     */

    public List<CloudVendor> listByDcId(Long dcId) {
        String sql = "select a.*,b.name env_name from cloud_vendor a left join environment b on a.env_id = b.id where a.is_deleted = 0 ";
        Map<String, Object> paramMap = Maps.newHashMap();
        if (null != dcId && 0L != dcId) {
            sql += " and a.dc_id = :dcId";
            paramMap.put("dcId", dcId);
        }
        return this.list(CloudVendor.class, sql, paramMap);
    }

    public List<CloudVendor> listByIds(List<Long> ids) {
        String sql = "select * from cloud_vendor where is_deleted = 0 and id in (:ids)";
        return this.list(CloudVendor.class, sql, MapTools.simpleMap("ids", ids));
    }

    public List<CloudVendor> listByIds(List<Long> ids, List<String> types) {
        String sql = "select * from cloud_vendor where is_deleted = 0 and id in (:ids)";
        Map<String, Object> simpleMap = MapTools.simpleMap("ids", ids);
        if (!ListTool.isEmpty(types)) {
            sql += " and type in (:types) ";
            simpleMap.put("types", types);
        }
        return this.list(CloudVendor.class, sql, simpleMap);
    }

    public CloudVendor getByRegion(String region, String zone, String type) {
        String sql = "select a.* from cloud_vendor a where a.is_deleted = 0 and a.region = :region and a.availablitiy_zone = :zone and a.type = :type";
        Map<String, Object> paramMap = MapTools.simpleMap("region", region);
        paramMap.put("zone", zone);
        paramMap.put("type", type);
        List<CloudVendor> list = this.list(CloudVendor.class, sql, paramMap);
        if (list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    public CloudVendor getNsxVendor(String region, String zone) {
        String sql = "select a.* from cloud_vendor a left join nsx_vcenter_relation b on b.nsx_vendor_id = a.id left join cloud_vendor c on c.id = b.vcenter_vendor_id where a.is_deleted = 0 and c.region = :region and c.availablitiy_zone = :zone";
        Map<String, Object> paramMap = MapTools.simpleMap("region", region);
        paramMap.put("zone", zone);
        List<CloudVendor> list = this.list(CloudVendor.class, sql, paramMap);
        if (list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    public CloudVendor getInternalNsxVendor() {
        String sql = "select a.* from cloud_vendor a where a.is_deleted = 0 and a.type = 'NSX'";
        List<CloudVendor> list = this.list(CloudVendor.class, sql, new HashMap<>(8));
        if (list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    public CloudVendor queryByBarborId(Long harborId) {
        String sql = "select a.* from cloud_vendor a  where a.is_deleted = 0 and a.harbor_id = :harborId";
        Map<String, Object> paramMap = MapTools.simpleMap("harborId", harborId);
        List<CloudVendor> list = this.list(CloudVendor.class, sql, paramMap);
        if (list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    public List<CloudVendor> listByCatalogId(Long catalogId) {
        String sql = "select a.* from cloud_vendor a  where a.is_deleted = 0 and find_in_set(:catalogId,a.catalog_ids) ";
        Map<String, Object> paramMap = MapTools.simpleMap("catalogId", catalogId);
        return this.list(CloudVendor.class, sql, paramMap);
    }

    public boolean updateBillFactor(Long id, BigDecimal billFactor) {
        String sql = "update cloud_vendor set bill_factor = :billFactor where id = :id";
        Map<String, Object> paramMap = MapTools.simpleMap("billFactor", billFactor);
        paramMap.put("id", id);
        return this.execute(sql, paramMap) > 0;
    }

    // 资源分配sql
    public List<ResourceAllocationVo> queryOrderByVendor(Date date) {
        String sql = "SELECT " +
                " cv.id , " +
                " cv.type , " +
                " cv.`name` as cloudPlatform, " +
                " count(*)  as virtualMachineCount, " +
                " sum(cs.cpu) as cpuCores, " +
                " sum(cs.memory) as memoryGB, " +
                " sum(cs.disk) as diskGB " +
                " FROM  " +
                " cloud_vendor cv " +
                " LEFT JOIN cloud_server cs ON cs.vendor_id = cv.id  " +
                " WHERE " +
                " cv.is_deleted = 0  " +
                " AND cs.is_deleted = 0  " +
                " AND year(cs.gmt_create) = year(:date)  " +
                " AND month(cs.gmt_create) = month(:date)  " +
                "  group by cv.id ";
        Map<String, Object> paramMap = MapTools.simpleMap("date", date);
        List<Map<String, Object>> list = this.list(sql, paramMap);
        List<ResourceAllocationVo> resultList = new ArrayList<>();
        for (Map<String, Object> map : list) {
            Long id = (Long) map.get("id");
            String type = (String) map.get("type");
            String cloudPlatform = (String) map.get("cloudPlatform");
            Long virtualMachineCount = (Long) map.get("virtualMachineCount");
            BigDecimal cpuCores = (BigDecimal) map.get("cpuCores");
            BigDecimal memoryGB = (BigDecimal) map.get("memoryGB");
            BigDecimal diskGB = (BigDecimal) map.get("diskGB");

            ResourceAllocationVo resourceAllocationVo = new ResourceAllocationVo(id, type, cloudPlatform, virtualMachineCount.intValue(), cpuCores.intValue(), memoryGB.toString(), diskGB.intValue());
            resultList.add(resourceAllocationVo);
        }
        return resultList;
    }
}
