package com.iteaj.thinking.design.monitoring.handle.time;


import com.iteaj.thinking.design.monitoring.*;
import com.iteaj.thinking.design.monitoring.record.TimeRecord;

import java.lang.reflect.Method;

/**
 * Create Date By 2016/10/28
 * <p>生成时间监控动作的工厂</p> <br>
 *
 * @author iteaj
 * @see #getMonitoringAction(Method, Class) 用来创建时间监控动作{@link MonitoringAction}
 * @since 1.7
 */
public abstract class TimeMonitoringActionFactory
        extends MonitoringActionFactoryAbstract<TimeRecord> {

    @Override
    protected MonitoringAction getMonitoringAction(Method method, Class target) {
        final TimeMonitoringActionFactory handle = this;
        return new MonitoringAction<TimeRecord>(method, target) {
            /**被监控方法执行后的时间*/
            private long afterTime;
            /**被监控方法执行前的时间*/
            private long beforeTime;
            /**是否异常*/
            private boolean isException;

            @Override
            public String getIdentifier() {
                return handle.getIdentifier();
            }

            @Override
            protected void beforeMethodAction(Method method) {
                beforeTime = System.currentTimeMillis();
            }

            @Override
            protected void afterMethodAction(Method method) {
                afterTime = System.currentTimeMillis();
            }

            @Override
            public void throwableAction(Throwable throwable, Method method) {
                this.isException = true;
            }

            @Override
            protected boolean isMatchingMonitoringActionFactory(MonitoringActionFactoryAbstract handleAbstract) {
                if (handleAbstract instanceof TimeMonitoringActionFactory)
                    return true;

                return false;
            }

            @Override
            protected TimeRecord createRecord() {
                TimeRecord record = new TimeRecord(this, afterTime - beforeTime);
                record.setExtra(MonitoringUtils.getExtra());
                if (isException)
                    record.setRecordType(RecordType.Exception);

                return record;
            }
        };
    }

    /**
     * 作为监控动作的标识
     *
     * @return
     */
    public abstract String getIdentifier();

    @Override
    public boolean isMatchingRecordType(Class<MonitoringRecord> clazz) {
        if (clazz == null) return false;

        if (TimeRecord.class.isAssignableFrom(clazz))
            return true;

        return false;
    }

    /**
     * 此监控动作{@link TimeMonitoringActionFactory}对象的监控记录类型为{@link TimeRecord}
     *
     * @return
     */
    @Override
    public Class<TimeRecord> getMonitoringRecordType() {
        return TimeRecord.class;
    }

}
