package com.bocloud.ims.service.thread;

import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.bocloud.cmp.driver.compute.SnapshotDriver;
import com.bocloud.cmp.driver.storage.VolumeDriver;
import com.bocloud.cmp.model.SnapshotModel;
import com.bocloud.cmp.model.VolumeModel;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.RequestContext;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.VendorTaskMsg;
import com.bocloud.ims.entity.resource.Volume;
import com.bocloud.ims.entity.resource.VolumeTemplate;
import com.bocloud.ims.repository.resource.VolumeTemplateRepository;
import com.bocloud.ims.service.transporter.vendor.SmartxTransporter;

public class SmartVolumeBuilder implements VolumeBuilder {

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

    private final SmartxTransporter smartTransporter;
    private final VolumeDriver volumeDriver;
    private final SnapshotDriver snapshotDriver;
    private final VolumeTemplateRepository volumeTemplateRepository;
    private final CloudVendor cloudVendor;
    private final VolumeModel paramModel;

    private final RequestContext context;

    public SmartVolumeBuilder(SmartxTransporter smartTransporter,
                              VolumeDriver volumeDriver, SnapshotDriver snapshotDriver,
                              VolumeTemplateRepository volumeTemplateRepository,
                              CloudVendor cloudVendor, VolumeModel volumeModel,
                              RequestContext context) {
        this.smartTransporter = smartTransporter;
        this.volumeDriver = volumeDriver;
        this.snapshotDriver = snapshotDriver;
        this.volumeTemplateRepository = volumeTemplateRepository;
        this.cloudVendor = cloudVendor;
        this.paramModel = volumeModel;
        this.context = context;
    }


    @Override
    public BocloudResult<Volume> build() {
        Volume volume = new Volume();
        volume.setName(paramModel.getName());
        try {
            BocloudResult bocloudResult;
            if ("空白卷".equals(paramModel.getType())) {
                bocloudResult = volumeDriver.create(cloudVendor.getUuid(), null, null, paramModel);
            } else if ("卷".equals(paramModel.getType())) {
                bocloudResult = volumeDriver.copyVolume(cloudVendor.getUuid(), null, paramModel);
            } else if ("快照".equals(paramModel.getType())) {
                SnapshotModel snapshotModel = new SnapshotModel();
                snapshotModel.setSnapshotUuid(paramModel.getSnapshotUuid());
                snapshotModel.setSnapshotType("VOLUME");
                snapshotModel.setRebuildVolume(paramModel);
                bocloudResult = snapshotDriver.rebuild(cloudVendor.getUuid(), null, snapshotModel);
            } else {
                return new BocloudResult<>(false, "不支持的卷类型");
            }

            if (bocloudResult.isFailed()) {
                logger.error("订购云硬盘失败: {}", bocloudResult.getMessage());
                return new BocloudResult<>(false, volume, bocloudResult.getMessage());
            }
            String taskUuid = bocloudResult.getData().toString();

            VendorTaskMsg taskMsg = smartTransporter.getTask(cloudVendor, taskUuid, context.getTarget());
            if (taskMsg.getSmartFailed()) {
                logger.error("订购云硬盘失败: {}", taskMsg.getSmartFinalErrorMessage());
                return new BocloudResult<>(false, volume, taskMsg.getSmartFinalErrorMessage());
            }
            String volumeUuid = taskMsg.getTargetUuid();

            bocloudResult = volumeDriver.detail(volumeUuid, cloudVendor.getUuid(), null);
            if (bocloudResult.isFailed()) {
                logger.error("订购云硬盘失败: {}", bocloudResult.getMessage());
                return new BocloudResult<>(false, volume, bocloudResult.getMessage());
            }
            VolumeModel volumeModel = (VolumeModel) bocloudResult.getData();

            String templateUuid = volumeModel.getVolumeTemplateUuid();
            VolumeTemplate template = volumeTemplateRepository.getByUuid(templateUuid);

            smartTransporter.convert(volumeModel, volume);
            volume.setVendorId(cloudVendor.getId());
            volume.setTemplateId(template.getId());
            volume.setCreatorId(context.getTarget());
            volume.setGmtCreate(new Date());
            return new BocloudResult<>(true, volume, "success");
        } catch (Exception e) {
            logger.error("订购云硬盘失败：{}", e.getMessage(), e);
            return new BocloudResult<>(false, volume, e.getMessage());
        }
    }

    @Override
    public BocloudResult<Volume> call() throws Exception {
        return this.build();
    }
}
