package com.bocloud.ims.service.scheduler.scheduler;


import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.compute.HostSeaDriver;
import com.bocloud.cmp.driver.compute.OsHostDriver;
import com.bocloud.cmp.driver.compute.ServerDriver;
import com.bocloud.cmp.driver.storage.StorageDriver;
import com.bocloud.cmp.driver.storage.VolumeDriver;
import com.bocloud.cmp.entity.enums.CloudProvider;
import com.bocloud.cmp.model.ServerModel;
import com.bocloud.cmp.model.VolumeModel;
import com.bocloud.cmp.model.powervc.PowervcHmcServerModel;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.ims.entity.resource.CloudServer;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.Server;
import com.bocloud.ims.entity.resource.Storage;
import com.bocloud.ims.entity.resource.powervc.HostSeaAdapter;
import com.bocloud.ims.entity.resource.powervc.PowervcRedisKeyBuilder;
import com.bocloud.ims.interfaces.resource.CloudVendorService;
import com.bocloud.ims.repository.resource.CloudServerRepository;
import com.bocloud.ims.repository.resource.ServerRepository;
import com.bocloud.ims.repository.resource.StorageRepository;
import com.bocloud.ims.service.transporter.vendor.PowervcTransporter;
import com.bocloud.service.core.CurrentService;

/**
 * powervc定时更新云主机的状态，RMC连接状态和sea状态
 */
@Component
public class PowervcScheduler {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private CurrentService service;
    @Autowired
    private ServerDriver serverDriver;
    @Autowired
    private HostSeaDriver hostSeaDriver;
    @Autowired
    private CloudVendorService cloudVendorService;
    @Autowired
    private CloudServerRepository cloudServerRepository;
    @Autowired
    private PowervcTransporter powervcTransportor;
    @Autowired
    private ServerRepository serverRepository;
    @Autowired
    private StorageRepository storageRepository;
    @Autowired
    private OsHostDriver osHostDriver;
    @Autowired
    private StorageDriver storageDriver;
    @Autowired
    private VolumeDriver volumeDriver;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Scheduled(cron = "${powervc.process.scheduler:0 0/5 * * * ?}")
    public void processCloudServer() {
        if (!service.isLeader()) {
            return;
        }
        List<CloudVendor> vendors = this.cloudVendorService.listAll();
        for (CloudVendor vendor : vendors) {
            if (CloudProvider.POWERVC.name().equals(vendor.getType())) {
                logger.info("开始定时更新Powervc云主机...");
                BocloudResult bocloudResult = serverDriver.list(vendor.getUuid(), null);
                if (bocloudResult.isFailed()) {
                    logger.error("获取Powervc平台[" + vendor.getName() + "]的所有云主机信息失败：" + bocloudResult.getMessage());
                    continue;
                }
                List<ServerModel> serverModels = (List<ServerModel>) bocloudResult.getData();
                if (serverModels != null && serverModels.size() > 0) {
                    for (ServerModel serverModel : serverModels) {
                        CloudServer cloudServer = cloudServerRepository.getByInstanceId(serverModel.getInstanceId());
                        if (cloudServer == null) {
                            logger.info(
                                    "发现Powervc平台[" + vendor.getName() + "]存在云主机[" + serverModel.getName() + "]而CMP中不存在该云主机，该云主机已被忽略");
                            continue;
                        }
                        cloudServer.setStatus(serverModel.getStatus());
                        cloudServer.setProps(serverModel.getProps());
                        cloudServerRepository.update(cloudServer);
                        logger.info("更新Powervc平台[" + vendor.getName() + "]云主机[" + serverModel.getName() + "]状态为["
                                + serverModel.getStatus() + "]");
                    }
                }
                logger.info("定时更新Powervc云主机完成");
            }
        }
    }

    @Scheduled(cron = "${powervc.process.scheduler:0 0/5 * * * ?}")
    public void processHostSea() {
        if (!service.isLeader()) {
            return;
        }
        List<CloudVendor> vendors = this.cloudVendorService.listAll();
        for (CloudVendor vendor : vendors) {
            if (CloudProvider.POWERVC.name().equals(vendor.getType())) {
                logger.info("开始定时更新Powervc主机SEA...");
                BocloudResult bocloudResult = hostSeaDriver.list(vendor.getUuid());
                if (bocloudResult.isFailed()) {
                    logger.error("获取Powervc平台[" + vendor.getName() + "]的所有主机SEA失败：" + bocloudResult.getMessage());
                    continue;
                }
                List<HostSeaAdapter> hostSeaAdapters = (List<HostSeaAdapter>) bocloudResult.getData();
                powervcTransportor.syncSea(vendor, hostSeaAdapters, 1L);
                logger.info("定时更新Powervc主机SEA完成");
            }
        }
    }

    @Scheduled(cron = "${powervc.process.scheduler:0 0/5 * * * ?}")
    public void processUnmanagedPowervm() {
        if (!service.isLeader()) {
            return;
        }
        List<CloudVendor> vendors = this.cloudVendorService.listAll();
        for (CloudVendor vendor : vendors) {
            if (CloudProvider.POWERVC.name().equals(vendor.getType())) {
                logger.info("开始定时更新可供Powervc管理的云主机信息...");
                List<Server> servers = serverRepository.listByVendor(vendor.getId());
                if (servers != null && servers.size() > 0) {
                    for (Server server : servers) {
                        String redisKey = PowervcRedisKeyBuilder.buildForVM(vendor.getId(), server.getId());
                        ValueOperations<String, String> redisOps = redisTemplate.opsForValue();
                        BocloudResult bocloudResult = osHostDriver.allServers(vendor.getUuid(), server.getHostname());
                        if (bocloudResult.isFailed()) {
                            logger.warn("获取Powervc平台[" + vendor.getName() + "]主机[" + server.getName() + "]的可供管理的云主机失败：" + bocloudResult.getMessage());
                            continue;
                        }
                        JSONObject jsonObject = JSON.parseObject(bocloudResult.getData().toString());
                        List<PowervcHmcServerModel> hmcServers = jsonObject.getJSONArray("servers").toJavaList(PowervcHmcServerModel.class);
                        // 过滤掉已经被管理进来的
                        hmcServers.removeIf(PowervcHmcServerModel::getManaged);
                        // 放进redis
                        redisOps.set(redisKey, JSON.toJSONString(hmcServers));
                    }
                }
                logger.info("定时更新可供Powervc管理的云主机信息完成");
            }
        }
    }

    @Scheduled(cron = "${powervc.process.scheduler:0 0/5 * * * ?}")
    public void processUnmanagedVolume() {
        if (!service.isLeader()) {
            return;
        }
        List<CloudVendor> vendors = this.cloudVendorService.listAll();
        for (CloudVendor vendor : vendors) {
            if (CloudProvider.POWERVC.name().equals(vendor.getType())) {
                logger.info("开始定时更新可供Powervc管理的存储卷信息...");
                List<Storage> storages = storageRepository.listByVendor(vendor.getId());
                if (storages != null && storages.size() > 0) {
                    for (Storage storage : storages) {
                        String redisKey = PowervcRedisKeyBuilder.buildForVolume(vendor.getId(), storage.getId());
                        ValueOperations<String, String> redisOps = redisTemplate.opsForValue();
                        BocloudResult bocloudResult = volumeDriver.allVolumes(vendor.getUuid(), storage.getHost());
                        if (bocloudResult.isFailed()) {
                            logger.warn("获取Powervc平台[" + vendor.getName() + "]存储器[" + storage.getName() + "]的可供管理的存储卷失败：" + bocloudResult.getMessage());
                            continue;
                        }
                        List<VolumeModel> volumes = (List<VolumeModel>) bocloudResult.getData();
                        // 过滤掉已经被管理进来的
                        volumes.removeIf(VolumeModel::getManaged);
                        // 放进redis
                        redisOps.set(redisKey, JSON.toJSONString(volumes));
                    }
                }
                logger.info("定时更新可供Powervc管理的存储卷信息完成");
            }
        }
    }
}
