package de.tu_darmstadt.tk.SmartHomeNetworkSim.view.menuBar;

import java.util.LinkedList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JMenu;
import javax.swing.JMenuItem;

import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.Controller;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.ExampleAnomalyController;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.NetworkController;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Connection;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ConnectionPrecision;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PrecisionLink;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.BoolSensor;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.FloatSensor;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler.NormalDistributionHandler;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.simpleImplementation.SimpleProtocol;

/**
 * Menu which allows simple insertion of anomalies into the network
 * 
 * @author Andreas T. Meyer-Berg
 */
public class MenuBarInsertAnomalies extends JMenu implements Observer {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2522406981845530518L;
	
	/**
	 * Controller for manipulating the network
	 */
	private Controller controller;
	
	/**
	 * Menu for denial of service attacks
	 */
	private JMenu mnDos;
	
	/**
	 * Menu for distributed denial of service attacks
	 */
	private JMenu mnDDos;
	
	/**
	 * Menu for letting the device crash
	 */
	private JMenu mnCrash;
	
	/**
	 * Menu for Value Anomalies
	 */
	private JMenu mnValueAnomaly;
	
	/**
	 * Anomaly Controller
	 */
	private ExampleAnomalyController anomController;
	
	/**
	 * Create a new MenuBar for anomaly insertion
	 * @param controller main Controller of the framework
	 */
	public MenuBarInsertAnomalies(Controller controller) {
		super("Insert Example Anomaly");
		this.controller = controller;
		this.anomController = controller.getNetworkController().getAnomalyController();
		initialize();
		this.update(null, null);
		this.controller.addObserver(this);
	}

	private void initialize() {
		mnDos = new JMenu("Denial of Service");
		this.add(mnDos);
		
		mnDDos = new JMenu("Distributed Denial of Service");
		this.add(mnDDos);
		
		mnCrash = new JMenu("Crash Device");
		this.add(mnCrash);
		
		mnValueAnomaly = new JMenu("Value Anomaly");
		this.add(mnValueAnomaly);	
	}
	
	@Override
	public void update(Observable o, Object arg) {
		mnDos.removeAll();
		mnDDos.removeAll();
		mnCrash.removeAll();
		mnValueAnomaly.removeAll();
		
		for(SmartDevice d : controller.getNetworkController().getVisibleSmartDevices()) {
			/**
			 * DDos Target Menu Item, which opens a DDosCreation Menu
			 */
			JMenuItem mntmDDosTarget = new JMenuItem("Destination: "+d.getName());
			mntmDDosTarget.addActionListener(a->anomController.openDDosCreationMenu(d, (List<SmartDevice>)controller.getNetworkController().getVisibleSmartDevices()));
			mnDDos.add(mntmDDosTarget);
			/**
			 * Dos creation menus
			 */
			JMenu mntmDosSource = new JMenu("Source: "+d.getName());
			for(SmartDevice t: controller.getNetworkController().getVisibleSmartDevices()){
				if(d==t)continue;
				JMenuItem mntmDosTarget = new JMenuItem("Destination: " +t.getName());
				mntmDosTarget.addActionListener(a->anomController.runDosAttack(d,t));
				mntmDosSource.add(mntmDosTarget);
			}
			mnDos.add(mntmDosSource);
			/**
			 * Menus to crash a device
			 */
			JMenuItem crashDevice = new JMenuItem(d.getName());
			crashDevice.addActionListener(a->anomController.crashDevice(d));
			mnCrash.add(crashDevice);
			/**
			 * Value Anomalies menus
			 */
			if(d instanceof BoolSensor) {
				BoolSensor sensor = (BoolSensor)d;
				JMenuItem itm = new JMenuItem(d.getName());
				itm.addActionListener(a->sensor.setBSval(!sensor.getBSval()));
			}else if(d instanceof FloatSensor) {
				FloatSensor sensor = (FloatSensor)d;
				JMenuItem itm = new JMenuItem(d.getName());
				itm.addActionListener(a->{
					sensor.setFSmax(100);
					sensor.setFSval(80);
				});
				mnValueAnomaly.add(itm);
			}
		}
		/**
		 * Only enable not empty menus
		 */
		mnCrash.setEnabled(mnCrash.getMenuComponentCount()!=0);
		mnDos.setEnabled(mnDos.getMenuComponentCount()!=0);
		mnDDos.setEnabled(mnDDos.getMenuComponentCount()!=0);
		mnValueAnomaly.setEnabled(mnValueAnomaly.getMenuComponentCount()!=0);
	}

}
