package com.liquidnet.service.reconciliation.util;

import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.common.cache.redisson.util.RedisLockUtil;
import com.liquidnet.commons.lang.util.StringUtil;
import com.liquidnet.commons.lang.util.spring.SpringUtils;
import com.liquidnet.service.reconciliation.biz.ReconciliationMainBiz;
import com.liquidnet.service.reconciliation.constant.ReconConstants.LockTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
@Component
public class FundFlowUtil {
	@Autowired
	private RedisLockUtil redisLockUtil;

	@Autowired
	private ReconciliationMainBiz reconciliationMainBiz;

	ExecutorService executor = Executors.newFixedThreadPool(16);

    private void _run(final String bankChannel,Date beginDate, Date endDate) {
		reconciliationMainBiz.accountingMain(bankChannel,beginDate,endDate);
	}

    public void executorThread(final String bankChannel,Date beginDate, Date endDate) {
		executor.execute(new Runnable() {
			public void run() {
				_run(bankChannel,beginDate,endDate);
			}
		});
    }

//    public Boolean accountingMain(final String bankChannel) {
//		try {
//			//创建一个Callable
//			Callable myCallable = new Callable() {
//					@Override
//					public Boolean call() throws Exception {
//						try {
//							_run(bankChannel);
//						} catch (RuntimeException e) {
//							e.printStackTrace();
//							return Boolean.FALSE;
//						}
//						return Boolean.TRUE;
//					}
//			};
//			Object result = executor.submit(myCallable).get();
//			return (Boolean)result;
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//		return Boolean.FALSE;
//	}

	public Boolean accountingMain(final String bankChannel,Date beginDate, Date endDate) {
		try {
			_run(bankChannel,beginDate,endDate);
		} catch (RuntimeException e) {
			e.printStackTrace();
			return Boolean.FALSE;
		}
		return Boolean.TRUE;
	}

    /**
	 * 加锁方法
	 */
    public static boolean lockUtils(String bankChannel, String lockType) {
		Boolean isLocked  =  null;
		try {
			isLocked  = RedisLockUtil.tryLock(LockTypeEnum.getKeyPrefixByCode(lockType) + bankChannel.toLowerCase(),10,600);
		} catch (Exception e) {
			e.printStackTrace();
			if(LockTypeEnum.ACCOUNTING_LOCK.getCode() == lockType){
			log.info("网关编号" + bankChannel + ",获取对账锁失败：" + e.getMessage());
			}else if(LockTypeEnum.UPLOAD_LOCK.getCode() == lockType){
			log.info("网关编号" + bankChannel + ",获取上传锁失败：" + e.getMessage());
			}
			return false;
		}

		// 锁：空闲状态
		if (StringUtil.isNotNull(isLocked) && isLocked) {
			if(LockTypeEnum.ACCOUNTING_LOCK.getCode() == lockType){
				log.info("网关编号" + bankChannel + ",获取对账锁成功");
			}else if(LockTypeEnum.UPLOAD_LOCK.getCode() == lockType){
				log.info("网关编号" + bankChannel + ",获取上传锁成功");
			}
			return true;
		}else{
			if(LockTypeEnum.ACCOUNTING_LOCK.getCode() == lockType){
				log.info("网关编号" + bankChannel + ",获取对账锁失败：");
			}else if(LockTypeEnum.UPLOAD_LOCK.getCode() == lockType){
				log.info("网关编号" + bankChannel + ",获取上传锁失败：");
			}
			return false;
		}
    }

    public static void releaseLock(String bankChannel,String lockType) {
		// 释放锁
		RedisLockUtil.unlock(LockTypeEnum.getKeyPrefixByCode(lockType) + bankChannel.toLowerCase());
		if(LockTypeEnum.ACCOUNTING_LOCK.getCode() == lockType){
			log.info("网关编号" + bankChannel + ",释放对账锁成功");
		}else if(LockTypeEnum.UPLOAD_LOCK.getCode() == lockType){
			log.info("网关编号" + bankChannel + ",释放上传锁成功");
		}
    }
}
