package com.buy507.mall.portal.component;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;

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

import com.buy507.mall.common.util.Constants;
import com.buy507.mall.model.UmsMember;
import com.buy507.mall.portal.service.InitDistributionService;

/**
 * 作用：会员注册时递归更新上级团队成员数量
 * 会员购买商品确认收货时也需要更新上级团队成员数量，使用redis分布式锁
 * @author wuming
 *
 */
@Component
public class TeamMemberNumberHanderQueue implements CommandLineRunner {

	private static final Logger LOGGER = LoggerFactory.getLogger(TeamMemberNumberHanderQueue.class);
	
	private static LinkedBlockingQueue<UmsMember> queue = new LinkedBlockingQueue<>();
	
	@Autowired
    private RedisLock redisLock;
	
	@Autowired
	private InitDistributionService distributionService;
	
	@Autowired
    private ExecutorService executorService;

	@Override
	public void run(String... args) throws Exception {
		executorService.execute(new Runnable() {

			@Override
			public void run() {
				while(true) {
					UmsMember member = null;
					try {
						LOGGER.info("team member number handler queue size: {}", queue.size());
						
						member = queue.take();
						LOGGER.info("team member number handler start: {}", member.getId());
						
						while(true) {
							long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
							if(redisLock.lock(Constants.LOCK_TEAM_MEMBER_NUM, String.valueOf(time))) {
								distributionService.updateUpTeamMemberNumberForAddInviter(member);
								redisLock.unlock(Constants.LOCK_TEAM_MEMBER_NUM, String.valueOf(time));
								break;
							}
						}
						
						LOGGER.info("team member number handler end: {}", member.getId());
						LOGGER.info("team member number handler queue size: {}", queue.size());
					} catch (InterruptedException e) {
						LOGGER.error("team member number handler failed");
						e.printStackTrace();
					} catch (Exception e) {
						if(member != null) {
							LOGGER.error("team member number handler failed: {}", member.getId());
						} else {
							LOGGER.error("team member number handler failed");
						}
						e.printStackTrace();
					}
				}
					
			}
			
		});
	}
	
	/**
	 * @param order
	 */
	public static void addMemberToQueue(UmsMember member) { 
		try {
			queue.put(member);
		} catch (InterruptedException e) {
			LOGGER.error("team member number handler failed: {}", member.getId());
			e.printStackTrace();
		}
	}
	
}
