package com.bocloud.ims.service.resource.hmc.db2driver;

import com.alibaba.fastjson.JSON;
import com.bocloud.cmp.driver.hmc.LogicalPartitionDriver;
import com.bocloud.cmp.model.hmc.HmdPartitionModel;
import com.bocloud.common.model.OperateResult;
import com.bocloud.common.model.RequestContext;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.hmc.HmdPartition;
import com.bocloud.ims.entity.resource.hmc.HmdProfile;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.repository.resource.hmc.HmdPartitionRepository;
import com.bocloud.ims.repository.resource.hmc.HmdProfileHeaRepository;
import com.bocloud.ims.repository.resource.hmc.HmdProfileRepository;
import com.bocloud.ims.repository.resource.hmc.HmdVirtualFabricAdapterRepository;
import com.bocloud.ims.repository.resource.hmc.HmdVirtualIoAdapterRepository;
import com.bocloud.ims.repository.resource.hmc.HmdVirtualNetworkAdapterRepository;
import com.bocloud.ims.repository.resource.hmc.HmdVirtualScsiAdapterRepository;
import com.bocloud.ims.service.utils.ResourceEventPublisher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;

import java.util.Collections;
import java.util.Map;

public class HmdCreatePartitionDb2Driver implements HmdDb2Driver {

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

    private final Long id;
    private final RequestContext requestContext;

    private final LogicalPartitionDriver logicalPartitionDriver;

    private final CloudVendorRepository vendorRepository;
    private final HmdPartitionRepository partitionRepository;
    private final HmdProfileRepository profileRepository;
    private final HmdVirtualIoAdapterRepository virtualIoAdapterRepository;
    private final HmdVirtualNetworkAdapterRepository virtualNetworkAdapterRepository;
    private final HmdVirtualScsiAdapterRepository virtualScsiAdapterRepository;
    private final HmdVirtualFabricAdapterRepository virtualFabricAdapterRepository;
    private final HmdProfileHeaRepository profileHeaRepository;

    private final ResourceEventPublisher resourceEventPublisher;

    public HmdCreatePartitionDb2Driver(Long id, RequestContext requestContext, ApplicationContext applicationContext) {
        this.id = id;
        this.requestContext = requestContext;
        this.logicalPartitionDriver = applicationContext.getBean(LogicalPartitionDriver.class);

        this.vendorRepository = applicationContext.getBean(CloudVendorRepository.class);
        this.partitionRepository = applicationContext.getBean(HmdPartitionRepository.class);
        this.profileRepository = applicationContext.getBean(HmdProfileRepository.class);
        this.virtualIoAdapterRepository = applicationContext.getBean(HmdVirtualIoAdapterRepository.class);
        this.virtualNetworkAdapterRepository = applicationContext.getBean(HmdVirtualNetworkAdapterRepository.class);
        this.virtualScsiAdapterRepository = applicationContext.getBean(HmdVirtualScsiAdapterRepository.class);
        this.virtualFabricAdapterRepository = applicationContext.getBean(HmdVirtualFabricAdapterRepository.class);
        this.profileHeaRepository = applicationContext.getBean(HmdProfileHeaRepository.class);

        this.resourceEventPublisher = applicationContext.getBean(ResourceEventPublisher.class);
    }

    private HmdPartition prepare() {
        HmdPartition partition = partitionRepository.getById(id);
        partitionRepository.extra(partition);
        partition.getProfiles().forEach(profileRepository::extra);
        for (HmdProfile profile : partition.getProfiles()) {
            if (profile.getIoAdapters() != null) {
                profile.getIoAdapters().forEach(virtualIoAdapterRepository::extra);
            }
            if (profile.getNetworkAdapters() != null) {
                profile.getNetworkAdapters().forEach(virtualNetworkAdapterRepository::extra);
            }
            if (profile.getScsiAdapters() != null) {
                profile.getScsiAdapters().forEach(virtualScsiAdapterRepository::extra);
            }
            if (profile.getFabricAdapters() != null) {
                profile.getFabricAdapters().forEach(virtualFabricAdapterRepository::extra);
            }
            if (profile.getHeas() != null) {
                profile.getHeas().forEach(profileHeaRepository::extra);
            }
        }
        return partition;
    }

    @Override
    public void run() {
        String operate = "hmc.partition";
        HmdPartition paramPartition = this.prepare();
        CloudVendor vendor = vendorRepository.query(paramPartition.getServer().getVendorId());
        Map<String, Long> map = Collections.singletonMap("vendorId", vendor.getId());
        try {
            HmdPartitionModel paramPartitionModel = JSON.parseObject(JSON.toJSONString(paramPartition), HmdPartitionModel.class);
            HmdPartitionModel resultPartitionModel = logicalPartitionDriver.create(vendor.getUuid(), paramPartitionModel);
            HmdPartition resultPartition = JSON.parseObject(JSON.toJSONString(resultPartitionModel), HmdPartition.class);
            partitionRepository.syncInstance(resultPartition, paramPartition, requestContext.getTarget());
            partitionRepository.stopAllPending(resultPartition.getId());

            String message = "逻辑分区" + paramPartition.getName() + "创建成功";
            OperateResult operateResult = new OperateResult(true, message, operate, map, OperateResult.OperateCategory.ResourceEvent, requestContext);
            resourceEventPublisher.send(operateResult);
        } catch (Exception e) {
            String message = "逻辑分区" + paramPartition.getName() + "创建失败：" + e.getMessage();
            logger.error(message, e);
            OperateResult operateResult = new OperateResult(true, message, operate, map, OperateResult.OperateCategory.ResourceEvent, requestContext);
            resourceEventPublisher.send(operateResult);
        }
    }
}
