package com.bocloud.ims.service.utils;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.ims.entity.topology.Instance;
import com.bocloud.ims.entity.topology.InstanceRelation;
import com.bocloud.ims.entity.topology.ModuleRelation;
import com.bocloud.ims.entity.topology.RelationDelay;
import com.bocloud.ims.interfaces.topology.InstanceRelationService;
import com.bocloud.ims.repository.topology.InstanceRelationRepository;
import com.bocloud.ims.repository.topology.InstanceRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.DelayQueue;

/**
 * @author tangcq
 * @since 2018-02-01
 */
public class RelationThread implements Runnable {
    Logger logger = LoggerFactory.getLogger(RelationThread.class);
    private DelayQueue<RelationDelay> queue;
    private InstanceRepository instanceRepository;
    private InstanceRelationRepository instanceRelationRepository;
    private InstanceRelationService instanceRelationService;

    public RelationThread(DelayQueue<RelationDelay> queue, InstanceRepository instanceRepository, InstanceRelationRepository instanceRelationRepository, InstanceRelationService instanceRelationService) {
        this.queue = queue;
        this.instanceRepository = instanceRepository;
        this.instanceRelationRepository = instanceRelationRepository;
        this.instanceRelationService = instanceRelationService;
    }

    @Override
    public void run() {
        Boolean res = true;
        while (res) {
            try {
                RelationDelay delay = queue.take();
                logger.info("正在处理关系：" + JSONObject.toJSONString(delay));
                InstanceRelation relation = delay.getInstanceRelation();
                // 找到目标的标志
                boolean findFlag = true;
                ModuleRelation moduleRelation = delay.getModuleRelation();
                Instance instance = delay.getInstance();
                if ("source".equals(delay.getBnameCloumn())) {
                    Instance object = instanceRepository.queryByBname(relation.getSourceModuleId(), relation.getGuidTemp());
                    if (object != null) {
                        relation.setSourceId(object.getId());
                        BocloudResult result = instanceRelationService.validate(moduleRelation, object, instance);
                        if (result.isFailed()) {
                            delay.setBnameCloumn("later");
                            findFlag = false;
                        } else {
                            instanceRelationRepository.save(relation);
                            logger.info("处理成功");
                        }
                    } else {
                        findFlag = false;
                    }
                } else if ("target".equals(delay.getBnameCloumn())) {
                    Instance object = instanceRepository.queryByBname(relation.getTargetModuleId(), relation.getGuidTemp());
                    if (object != null) {
                        relation.setTargetId(object.getId());
                        BocloudResult result = instanceRelationService.validate(moduleRelation, object, instance);
                        if (result.isFailed()) {
                            delay.setBnameCloumn("later");
                            findFlag = false;
                        } else {
                            instanceRelationRepository.save(relation);
                            logger.info("处理成功");
                        }
                    } else {
                        findFlag = false;
                    }
                } else if ("later".equals(delay.getBnameCloumn())) {
                    Instance object = instanceRepository
                            .query(instance.getId().equals(relation.getSourceId()) ? relation.getTargetId()
                                    : relation.getSourceId());
                    if (object != null) {
                        BocloudResult result = instanceRelationService.validate(moduleRelation, object, instance);
                        if (result.isFailed()) {
                            findFlag = false;
                        } else {
                            instanceRelationRepository.save(relation);
                            logger.info("处理成功");
                        }
                    } else {
                        findFlag = false;
                    }
                }
                // 3分钟还没找到目标 就丢弃不处理了
                if (!findFlag && ((System.currentTimeMillis() - relation.getGmtCreate().getTime()) < 1000L * 60 * 3)) {
                    logger.info("处理失败，一会儿再处理一次");
                    delay.setLastTime(System.currentTimeMillis());
                    queue.put(delay);
                } else if (!findFlag) {
                    logger.info("处理失败，丢弃，不在处理。");
                }
                logger.info("延迟处理的关系数量还有：" + queue.size());
            } catch (Exception e) {
                logger.error("处理关系错误" + e);
            }
            if (!res) {
                break;
            }
        }
    }

}
