package com.elab.log;

import com.dianping.cat.Cat;
import com.dianping.cat.message.Event;
import com.dianping.cat.message.Transaction;
import com.dianping.cat.message.internal.AbstractMessage;
import com.dianping.cat.message.internal.NullMessage;
import com.elab.log.utils.CatMsgConstants;
import com.elab.log.utils.CatMsgContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 线程上下文封装类
 *
 * @author : liukx
 * @create : 2018/10/26 17:12
 * @email : liukx@elab-plus.com
 */
public abstract class CatThreadProcess implements Runnable {

    private Logger logger = LoggerFactory.getLogger(CatThreadProcess.class);

    private String threadName;
    private String parentId;
    private String rootId;
    private String childId;
    protected Object object;


    public CatThreadProcess(String threadName, Object object) {
        this.threadName = threadName;
        this.object = object;
        CatMsgContext context = new CatMsgContext();
        Cat.logRemoteCallClient(context, Cat.getManager().getDomain());
        this.parentId = context.getProperty(Cat.Context.PARENT);
        this.rootId = context.getProperty(Cat.Context.ROOT);
        this.childId = context.getProperty(Cat.Context.CHILD);
    }

    /**
     * 具体执行的业务方法
     */
    public abstract void process();

    @Override
    public void run() {
        Transaction t = null;
        try {
            t = Cat.newTransaction(CatMsgConstants.LOCAL_THREAD_SERVER, this.threadName);
            Cat.Context context = new CatMsgContext();
            context.addProperty(Cat.Context.ROOT, this.rootId);
            context.addProperty(Cat.Context.PARENT, this.parentId);
            context.addProperty(Cat.Context.CHILD, this.childId);
            Cat.logRemoteCallServer(context);
            process();
            t.setStatus(Transaction.SUCCESS);
        } catch (Exception e) {
            logger.error("------ THREAD LOCAL Get cat msgtree error : ", e);
            Event event = Cat.newEvent("LOCAL_THREAD_CAT_ERROR", this.threadName);
            event.setStatus(e);
            completeEvent(event);
            t.addChild(event);
            t.setStatus(e.getClass().getSimpleName());
        } finally {
            t.complete();
            logger.debug("THREAD LOCAL CAT 调用完毕 ... ");
        }
    }

    private void completeEvent(Event event) {
        if (event != NullMessage.EVENT) {
            AbstractMessage message = (AbstractMessage) event;
            message.setCompleted(true);
        }
    }
}
