package com.wuban.tron.explore.handler;

import com.wuban.tron.explore.domain.TronAccount;
import com.wuban.tron.explore.domain.TronFreeze;
import com.wuban.tron.explore.entity.Address;
import com.wuban.tron.explore.fetch.AbstractJob;
import com.wuban.tron.explore.fetch.PersistThreadPool;
import com.wuban.tron.explore.fetch.PersistThreadPoolV2;
import com.wuban.tron.explore.service.AddressService;
import com.wuban.tron.explore.util.BigDecimalUtil;
import com.wuban.tron.explore.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.tron.common.utils.ByteArray;
import org.tron.walletserver.WalletApi;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;

/**
 *  <core>账户余额处理者服务接口方法实现类</core>
 *
 * @author sky
 * @date 2020/11/12
 */
@Slf4j
public class AddressBalanceHandler extends AbstractJob implements IAddressBalanceHandler<TronAccount> {

    private AddressService addressService;

    private PersistThreadPoolV2 threadPool;

    private final LinkedBlockingQueue<List<TronAccount>> dataList;

    public AddressBalanceHandler() {
        this.dataList = new LinkedBlockingQueue<>();
        addressService = SpringContextUtil.getBean(AddressService.class);
        threadPool = PersistThreadPoolV2.getInstance();
    }

    @Override
    public boolean execute() {
        final List<TronAccount> list = this.dataList.poll();
        if(list != null && list.size() != 0) {
            threadPool.getPool().execute(() -> flush(list));
        }
        return true;
    }

    @Override
    public void receive(List<TronAccount> e) throws InterruptedException {
        if (!CollectionUtils.isEmpty(e)) {
            this.dataList.put(e);
        }
    }

    @Override
    public void flush(List<TronAccount> e) {
        if (!CollectionUtils.isEmpty(e)) {
            TronAccount account = e.get(0);
            Address obj = new Address();

            String address = WalletApi.encode58Check(ByteArray.fromHexString(e.get(0).getAddress()));
            obj.setAddress(address);
            obj.setBalance(account.getBalance());

            // 冻结余额
            BigDecimal frozenBalance = new BigDecimal(0);
            List<TronFreeze> tronFreezes = account.getFrozen();
            if (!CollectionUtils.isEmpty(tronFreezes)) {
                for (int i = 0; i < tronFreezes.size(); i++) {
                    frozenBalance = BigDecimalUtil.getAdd(frozenBalance, new BigDecimal(tronFreezes.get(i).getFrozen_balance()));
                }
            }
            obj.setFrozenBalance(frozenBalance.longValue());

            this.addressService.updateById(obj);
            log.info("更新账户余额 {}", obj.toString());
        }
    }


}
