package com.ericsson.uecontrol.core;

import org.apache.log4j.Logger;

import java.io.Serializable;

/**
 * Base class for Ue behaviours that can be used by the executor
 *
 * Created by ezivkoc on 2014-07-15.
 */
public abstract class UeBehaviour implements Serializable{
    private static final Logger log = Logger.getLogger(UeBehaviour.class);

    private transient boolean running;
    private transient BehaviourExecutionListener execListener;
    private transient DataHandledListener datahandledListener;


    public synchronized void preRun() {
        running = true;
    }

    /**
     * Starts to run the behaviour, this method will block until the execution is done
     */
    public void run(){
        if(execListener != null) execListener.executionStarted();
        try {
            setProgress(0);
            execute();
        } catch(Exception e){
            if(execListener != null) execListener.exception(e);
            log.warn(null, e);
        }
        if(execListener != null) execListener.executionStopped();
    }

    /**
     * Will stop the currently running behaviour
     */
    public void terminate(){
        running = false;
    }

    /**
     * @return if currently running behaviour should be terminated
     */
    protected boolean stopExecution(){
        return !running;
    }


    public void setExecutionListener(BehaviourExecutionListener l){
        execListener = l;
    }

    protected void setProgress(float progress){
        if(execListener != null)
            execListener.progressChanged(progress);

        // TODO: This is a dirty way of updating the throughput, should be changed
        if(datahandledListener != null)
            datahandledListener.handledIncomingData(0);
    }

    public void setDataHandledListener(DataHandledListener listener) {
        datahandledListener = listener;
    }

    protected void setHandledIncomingData(long size){
        if(datahandledListener != null)
            datahandledListener.handledIncomingData(size);
    }
    protected void setHandledOutgoingData(long size){
        if(datahandledListener != null)
            datahandledListener.handledOutgoingData(size);
    }

    /**
     * Executes the behaviour, will block until behaviour has run to completion.
     */
    protected abstract void execute() throws Exception;

    /**
     * @return the short name of the behaviour
     */
    public abstract String getName();

    /**
     * @return a longer description of the behaviour
     */
    //public abstract String getDescription();

    /**
     * @return a nice String with the current settings
     */
    public abstract String toString();


    public static interface BehaviourExecutionListener {
        public void executionStarted();
        public void progressChanged(float progress);
        public void executionStopped();
        public void exception(Exception e);
    }

    public static interface DataHandledListener {
        public void handledIncomingData(long size);
        public void handledOutgoingData(long size);
    }
}
