package com.yanzuoguang.cloud.aop;

import com.yanzuoguang.util.thread.ThreadNext;
import com.yanzuoguang.util.vo.LogVo;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

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

/**
 * 获取当前日志对象
 *
 * @author 颜佐光
 */
@Component
public class LogBase implements ThreadNext.Next, InitializingBean {
    /**
     * 缓存队列
     */
    protected volatile LinkedBlockingQueue<LogVo> cache = new LinkedBlockingQueue<>();

    @Autowired
    protected List<LogFeign> logFeigns;

    private LogFeign logFeign;

    @Value("${yzg.log.base:false}")
    private boolean logBase;

    /**
     * Invoked by a BeanFactory after it has set all bean properties supplied
     * (and satisfied BeanFactoryAware and ApplicationContextAware).
     * <p>This method allows the bean instance to perform initialization only
     * possible when all bean properties have been set and to throw an
     * exception in the event of misconfiguration.
     *
     * @throws Exception in the event of misconfiguration (such
     *                   as failure to set an essential property) or if initialization fails.
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        ThreadNext.start(this, "save log error");
    }

    /**
     * 添加日志到缓存中,并不是立即添加,而是通过线程执行,防止对环境造成影响
     *
     * @param logVo
     */
    public void addLog(LogVo logVo) {
        cache.add(logVo);
    }

    /**
     * 执行下一个函数,出现异常会继续执行
     *
     * @return 是否继续执行
     * @throws Exception 异常信息
     */
    @Override
    public boolean next() throws Exception {
        if (!logBase) {
            cache.clear();
            return true;
        }

        if (logFeign == null) {
            for (LogFeign log : logFeigns) {
                if (log instanceof LogFeignDefault) {
                    if (logFeign == null) {
                        logFeign = log;
                    }
                } else {
                    logFeign = log;
                }
            }
        }


        while (cache.size() > 0) {
            LogVo item = cache.poll();
            if (item != null) {
                try {
                    logFeign.save(item);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
        return true;
    }

    /**
     * 沉睡时间
     *
     * @return
     */
    @Override
    public int getNextTime() {
        return 100;
    }
}