<commit_before>package nl.uu.trafficmas.simulationmodel;

import it.polito.appeal.traci.SumoTraciConnection;

import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;

import nl.uu.trafficmas.agent.Agent;
import nl.uu.trafficmas.agent.AgentSumo;
import nl.uu.trafficmas.agent.SUMODefaultAgent;
import nl.uu.trafficmas.agent.actions.AgentAction;
import nl.uu.trafficmas.agent.actions.SumoAgentAction;
import nl.uu.trafficmas.roadnetwork.Edge;
import nl.uu.trafficmas.roadnetwork.Lane;
import nl.uu.trafficmas.roadnetwork.Road;
import nl.uu.trafficmas.roadnetwork.RoadNetwork;
import de.tudresden.sumo.cmd.Simulation;
import de.tudresden.sumo.cmd.Vehicle;
import de.tudresden.sumo.util.SumoCommand;
import de.tudresden.ws.container.SumoStringList;

public class SimulationModelTraaS implements SimulationModel {

	SumoTraciConnection conn;
	String sumocfg;
	String sumoBin;
	private Socket sa;
	public static final int LOOK_AHEAD_DISTANCE = 100;
	public static final int OVERTAKE_DURATION = 5;
	
	public SimulationModelTraaS(String sumoBin, String sumocfg){
		this.sumoBin = sumoBin;
		this.sumocfg = sumocfg;
	}
	
	public SimulationModelTraaS(String address, int port) {
		// TODO Auto-generated constructor stub
		try {
			sa = new Socket(address, port);
			conn = new SumoTraciConnection(sa.getRemoteSocketAddress());
		} catch (IOException | InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public void initialize() {
		if(conn == null) {
			conn = initialize(sumoBin, sumocfg);
		}		
 	}	
	
	public static SumoTraciConnection initialize(String sumoBin, String sumocfg){
		SumoTraciConnection conn = new SumoTraciConnection(sumoBin, sumocfg);
		// Add an extra option.
		try {	
			//start TraCI
			conn.runServer();
	       //load routes and initialize the simulation
			conn.do_timestep();    
       }catch(Exception ex){ex.printStackTrace();}
		
		return conn;
	}
	
	@Override
	public void initializeWithOptions(HashMap<String,String> optionValueMap) {
		if(conn == null) {
			conn = initializeWithOptions(optionValueMap, sumoBin, sumocfg);
		}		
 	}		
	public static SumoTraciConnection initializeWithOptions(HashMap<String,String> optionValueMap, String sumoBin, String sumocfg){
		SumoTraciConnection conn = new SumoTraciConnection(sumoBin, sumocfg);
		// Add an extra option.
		for(Entry<String, String> keyValue : optionValueMap.entrySet()) {
			conn.addOption(keyValue.getKey(), keyValue.getValue());
		}
		try {	
			//start TraCI
			conn.runServer();
	       //load routes and initialize the simulation
			conn.do_timestep();    
       }catch(Exception ex){ex.printStackTrace();}
		
		return conn;
	}

	@Override
	public void close() {
		if(sa != null) {
			try {
				sa.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		conn.close();
	}
	
	@Override
	public void doTimeStep() {
		try {
			conn.do_timestep();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void addAgent(Agent agent, String routeID, int tick) {
		addAgent(agent, routeID, tick, conn);
	}
	
	/**
	 * Calls the method SimulationModelTraas.addAgentCommand(agent,routeID,tick)
	 * @param agent
	 * @param routeID
	 * @param tick
	 * @param conn
	 */
	public static void addAgent(Agent agent, String routeID, int tick, SumoTraciConnection conn){
		try {
			conn.do_job_set(addAgentCommand(agent, routeID, tick));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Returns the SumoCommand to add a single agent 'agent' at time 'tick' with route 'routeID' 
	 * and certain default values such as spawn speed and Vehicle Type.
	 * @param agent
	 * @param routeID
	 * @param tick
	 * @return a SumoCommand to add a single agent.
	 */
	public static SumoCommand addAgentCommand(Agent agent, String routeID, int tick) {
		return Vehicle.add(agent.agentID, "Car", routeID, tick, 0.0, Math.min(agent.getMaxComfySpeed(),3), (byte) 0);
	}
	
	@Override
	public HashMap<String, Agent> addAgents(HashMap<Agent, Integer> agentPairList) {
		return addAgents(agentPairList, conn);
	}
	
	/**
	 * Sends a list of commands to spawn Agents to SUMO via connection 'conn'. The agent data and spawn times are provided in 'agentPairList'. 
	 * Default values depending on the agentProfileType are added, like Color and MaxSpeed.
	 * @param agentPairList
	 * @param conn
	 * @return the HashMap containing all agents that will spawn in the simulation. 
	 */
	public static HashMap<String, Agent> addAgents(HashMap<Agent, Integer> agentPairList, SumoTraciConnection conn){
		HashMap<String, Agent> completeAgentMap = new LinkedHashMap<String, Agent>();
		ArrayList<SumoCommand> cmds = new ArrayList<>();
		
		try {
			for( Entry<Agent, Integer> agentPair : agentPairList.entrySet()){
				
				Agent agent = agentPair.getKey();
				// Use SUMO default settings for this agent.
				if(agent instanceof SUMODefaultAgent){
					cmds.add(addAgentCommand(agent, agent.getRouteID(), agentPair.getValue()));
					cmds.add(Vehicle.setColor(agent.agentID, ((AgentSumo) agent).getColor()));
					completeAgentMap.put(agent.agentID, agent);
				} else{
				// Otherwise, disable setSpeedMode, LaneChangeMode and set custom maxSpeed. 
					cmds.add(addAgentCommand(agent, agent.getRouteID(), agentPair.getValue()));
					cmds.add(Vehicle.setLaneChangeMode(agent.agentID, 0b1000000000));
					cmds.add(Vehicle.setSpeedMode(agent.agentID, 0b00001));
					cmds.add(Vehicle.setMaxSpeed(agent.agentID, agent.getMaxComfySpeed()));
					cmds.add(Vehicle.setColor(agent.agentID, ((AgentSumo) agent).getColor()));
					completeAgentMap.put(agent.agentID, agent);
				}
				// TODO: think of a way to express max comfy speed in a different way
			}
	
			if(agentPairList.size() > 0){
				conn.do_jobs_set(cmds);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return completeAgentMap;
	}
	
	@Override
	public HashMap<String, Agent> updateCurrentAgentMap(HashMap<String, Agent> completeAgentMap, HashMap<String, Agent> oldAgentMap) {
		return updateCurrentAgentMap(completeAgentMap, oldAgentMap, conn);
	}
	
	/**<commit_msg>:mouse: setLaneChangeMode to 0b1100000000<commit_after>package nl.uu.trafficmas.simulationmodel;

import it.polito.appeal.traci.SumoTraciConnection;

import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;

import nl.uu.trafficmas.agent.Agent;
import nl.uu.trafficmas.agent.AgentSumo;
import nl.uu.trafficmas.agent.SUMODefaultAgent;
import nl.uu.trafficmas.agent.actions.AgentAction;
import nl.uu.trafficmas.agent.actions.SumoAgentAction;
import nl.uu.trafficmas.roadnetwork.Edge;
import nl.uu.trafficmas.roadnetwork.Lane;
import nl.uu.trafficmas.roadnetwork.Road;
import nl.uu.trafficmas.roadnetwork.RoadNetwork;
import de.tudresden.sumo.cmd.Simulation;
import de.tudresden.sumo.cmd.Vehicle;
import de.tudresden.sumo.util.SumoCommand;
import de.tudresden.ws.container.SumoStringList;

public class SimulationModelTraaS implements SimulationModel {

	SumoTraciConnection conn;
	String sumocfg;
	String sumoBin;
	private Socket sa;
	public static final int LOOK_AHEAD_DISTANCE = 100;
	public static final int OVERTAKE_DURATION = 5;
	
	public SimulationModelTraaS(String sumoBin, String sumocfg){
		this.sumoBin = sumoBin;
		this.sumocfg = sumocfg;
	}
	
	public SimulationModelTraaS(String address, int port) {
		// TODO Auto-generated constructor stub
		try {
			sa = new Socket(address, port);
			conn = new SumoTraciConnection(sa.getRemoteSocketAddress());
		} catch (IOException | InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public void initialize() {
		if(conn == null) {
			conn = initialize(sumoBin, sumocfg);
		}		
 	}	
	
	public static SumoTraciConnection initialize(String sumoBin, String sumocfg){
		SumoTraciConnection conn = new SumoTraciConnection(sumoBin, sumocfg);
		// Add an extra option.
		try {	
			//start TraCI
			conn.runServer();
	       //load routes and initialize the simulation
			conn.do_timestep();    
       }catch(Exception ex){ex.printStackTrace();}
		
		return conn;
	}
	
	@Override
	public void initializeWithOptions(HashMap<String,String> optionValueMap) {
		if(conn == null) {
			conn = initializeWithOptions(optionValueMap, sumoBin, sumocfg);
		}		
 	}		
	public static SumoTraciConnection initializeWithOptions(HashMap<String,String> optionValueMap, String sumoBin, String sumocfg){
		SumoTraciConnection conn = new SumoTraciConnection(sumoBin, sumocfg);
		// Add an extra option.
		for(Entry<String, String> keyValue : optionValueMap.entrySet()) {
			conn.addOption(keyValue.getKey(), keyValue.getValue());
		}
		try {	
			//start TraCI
			conn.runServer();
	       //load routes and initialize the simulation
			conn.do_timestep();    
       }catch(Exception ex){ex.printStackTrace();}
		
		return conn;
	}

	@Override
	public void close() {
		if(sa != null) {
			try {
				sa.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		conn.close();
	}
	
	@Override
	public void doTimeStep() {
		try {
			conn.do_timestep();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void addAgent(Agent agent, String routeID, int tick) {
		addAgent(agent, routeID, tick, conn);
	}
	
	/**
	 * Calls the method SimulationModelTraas.addAgentCommand(agent,routeID,tick)
	 * @param agent
	 * @param routeID
	 * @param tick
	 * @param conn
	 */
	public static void addAgent(Agent agent, String routeID, int tick, SumoTraciConnection conn){
		try {
			conn.do_job_set(addAgentCommand(agent, routeID, tick));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Returns the SumoCommand to add a single agent 'agent' at time 'tick' with route 'routeID' 
	 * and certain default values such as spawn speed and Vehicle Type.
	 * @param agent
	 * @param routeID
	 * @param tick
	 * @return a SumoCommand to add a single agent.
	 */
	public static SumoCommand addAgentCommand(Agent agent, String routeID, int tick) {
		return Vehicle.add(agent.agentID, "Car", routeID, tick, 0.0, Math.min(agent.getMaxComfySpeed(),3), (byte) 0);
	}
	
	@Override
	public HashMap<String, Agent> addAgents(HashMap<Agent, Integer> agentPairList) {
		return addAgents(agentPairList, conn);
	}
	
	/**
	 * Sends a list of commands to spawn Agents to SUMO via connection 'conn'. The agent data and spawn times are provided in 'agentPairList'. 
	 * Default values depending on the agentProfileType are added, like Color and MaxSpeed.
	 * @param agentPairList
	 * @param conn
	 * @return the HashMap containing all agents that will spawn in the simulation. 
	 */
	public static HashMap<String, Agent> addAgents(HashMap<Agent, Integer> agentPairList, SumoTraciConnection conn){
		HashMap<String, Agent> completeAgentMap = new LinkedHashMap<String, Agent>();
		ArrayList<SumoCommand> cmds = new ArrayList<>();
		
		try {
			for( Entry<Agent, Integer> agentPair : agentPairList.entrySet()){
				
				Agent agent = agentPair.getKey();
				// Use SUMO default settings for this agent.
				if(agent instanceof SUMODefaultAgent){
					cmds.add(addAgentCommand(agent, agent.getRouteID(), agentPair.getValue()));
					cmds.add(Vehicle.setColor(agent.agentID, ((AgentSumo) agent).getColor()));
					completeAgentMap.put(agent.agentID, agent);
				} else{
				// Otherwise, disable setSpeedMode, LaneChangeMode and set custom maxSpeed. 
					cmds.add(addAgentCommand(agent, agent.getRouteID(), agentPair.getValue()));
					cmds.add(Vehicle.setLaneChangeMode(agent.agentID, 0b1100000000));
					cmds.add(Vehicle.setSpeedMode(agent.agentID, 0b00001));
					cmds.add(Vehicle.setMaxSpeed(agent.agentID, agent.getMaxComfySpeed()));
					cmds.add(Vehicle.setColor(agent.agentID, ((AgentSumo) agent).getColor()));
					completeAgentMap.put(agent.agentID, agent);
				}
				// TODO: think of a way to express max comfy speed in a different way
			}
	
			if(agentPairList.size() > 0){
				conn.do_jobs_set(cmds);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return completeAgentMap;
	}
	
	@Override
	public HashMap<String, Agent> updateCurrentAgentMap(HashMap<String, Agent> completeAgentMap, HashMap<String, Agent> oldAgentMap) {
		return updateCurrentAgentMap(completeAgentMap, oldAgentMap, conn);
	}
	
	/**
{'fraction_non_alphanumeric': 0.11098779134295228, 'fraction_numerical': 0.004994450610432853, 'mean_word_length': 4.208505367464905, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 3, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '260402', 'n_tokens_mistral': 4491, 'n_tokens_neox': 4024, 'n_words': 989}