package com.ctrip.xpipe.redis.console.migration.manager;

import com.ctrip.xpipe.api.observer.Observable;
import com.ctrip.xpipe.redis.console.dao.MigrationEventDao;
import com.ctrip.xpipe.redis.console.migration.model.MigrationCluster;
import com.ctrip.xpipe.redis.console.migration.model.MigrationEvent;
import com.ctrip.xpipe.redis.console.migration.status.MigrationStatus;
import com.ctrip.xpipe.redis.console.model.MigrationEventTbl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @author shyin
 *
 * Dec 8, 2016
 */
@Component
public class DefaultMigrationEventManager implements MigrationEventManager {
	private Logger logger = LoggerFactory.getLogger(getClass());
	
	@Autowired
	private MigrationEventDao migrationEventDao;
	private boolean initiated = false;
	
	private Map<Long, MigrationEvent> currentWorkingEvents = new HashMap<>();


	@Override
	public void addEvent(MigrationEvent event) {
		assureInit();
		event.addObserver(this);
		currentWorkingEvents.put(event.getEvent().getId(), event);
		logger.info("[AddEvent]{}",event.getEvent().getId());
	}

	@Override
	public MigrationEvent getEvent(long id) {
		assureInit();
		return currentWorkingEvents.get(id);
	}

	@Override
	public void removeEvent(long id) {
		assureInit();
		currentWorkingEvents.remove(id);
		logger.info("[RemoveEvent]{}", id);
	}

	private void assureInit() {
		if(!initiated) {
			synchronized (this) {
				if(!initiated) {
					this.initiated = true;
					load();
				}
			}
		}
	}
	
	private void load() {
		List<MigrationEventTbl> unfinishedTasks = migrationEventDao.findAllUnfinished();
		Set<Long> unfinishedIds = new HashSet<>();
		for(MigrationEventTbl unfinished : unfinishedTasks) {
			unfinishedIds.add(unfinished.getId());
		}
		
		for(Long id : unfinishedIds) {
			addEvent(migrationEventDao.buildMigrationEvent(id));
		}
	}

	@Override
	public void update(Object args, Observable observable) {
		MigrationEvent event = (MigrationEvent) args;
		int successCnt = 0;
		for(MigrationCluster cluster : event.getMigrationClusters()) {
			if(MigrationStatus.isTerminated(cluster.getStatus())) {
				++successCnt;
			}
		}
		if(successCnt == event.getMigrationClusters().size()) {
			removeEvent(((MigrationEvent) args).getEvent().getId());
		}
	}
}

@@ -603,16 +603,55 @@
 onent;%0A%0A
+import javax.annotation.PostConstruct;%0A
 import j
@@ -662,16 +662,16 @@
 util.*;%0A
-
 %0A/**%0A * 
@@ -1030,16 +1030,91 @@
 p%3C%3E();%0A%0A
+%09@PostConstruct%0A%09public void defaultMigrationEventManager()%7B%0A%09%09load();%0A%09%7D%0A%0A
 %0A%09@Overr
@@ -1163,32 +1163,16 @@
 vent) %7B%0A
-%09%09assureInit();%0A
 %09%09event.
@@ -1365,32 +1365,16 @@
 g id) %7B%0A
-%09%09assureInit();%0A
 %09%09return
@@ -1459,24 +1459,8 @@
 ) %7B%0A
-%09%09assureInit();%0A
 %09%09cu
@@ -1536,163 +1536,8 @@
 %09%7D%0A%0A
-%09private void assureInit() %7B%0A%09%09if(!initiated) %7B%0A%09%09%09synchronized (this) %7B%0A%09%09%09%09if(!initiated) %7B%0A%09%09%09%09%09this.initiated = true;%0A%09%09%09%09%09load();%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%09%7D%0A%09%0A
 %09pri
@@ -1555,16 +1555,17 @@
 oad() %7B%0A
+%0A
 %09%09List%3CM
@@ -1822,16 +1822,25 @@
 dIds) %7B%0A
+%09%09%09try%7B%0A%09
 %09%09%09addEv
@@ -1883,24 +1883,98 @@
 Event(id));%0A
+%09%09%09%7Dcatch(Throwable th)%7B%0A%09%09%09%09logger.error(%22%5Bload%5D%5Bevent%5D%22 + id, th);%0A%09%09%09%7D%0A
 %09%09%7D%0A%09%7D%0A%0A%09@Ov

load on postContruct