package de.tud.kom.p2psim.impl.vehicular.trafficlights;

import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.SimulationSetupExtractor;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.TrafficLightController;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkLink;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.trafficlights.TrafficLight;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.trafficlights.TrafficLightInformationComponent;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.trafficlights.TrafficLightState;
import de.tudresden.ws.container.SumoTLSController;
import de.tudresden.ws.container.SumoTLSProgram;

import java.util.List;
import java.util.Map;

public class DefaultTrafficLightInformationComponent implements TrafficLightInformationComponent {
    private Host host;

    private TrafficLightController controller;
    private SimulationSetupExtractor extractor;

    private String trafficLightId;
    private Double numberOfMessagesSent;

    public DefaultTrafficLightInformationComponent(Host host, TrafficLightController controller, SimulationSetupExtractor extractor) {
        this.host = host;

        this.controller = controller;
        this.extractor = extractor;
        this.numberOfMessagesSent = 0.0;
    }

    public void incrementNumberOfMessagesSent() {
        numberOfMessagesSent++;
    }

    public double getNumberOfMessagesSent() {
        return numberOfMessagesSent;
    }

    public TrafficLightController getController() {
        return controller;
    }

    @Override
    public void setTrafficLightId(String pTrafficLightId) {
        trafficLightId = pTrafficLightId;
    }

    @Override
    public void resetTrafficLightId() {
        trafficLightId = null;
    }

    @Override
    public boolean isValid() {
        return trafficLightId != null;
    }

    @Override
    public Location getTrafficLightLocation() {
        List<TrafficLight> trafficLights = controller.getAllTrafficLights();
        List<Location> intersections = controller.getAllIntersections(true);
        Location trafficLightLocation = null;

        for (int i = 0 ; i < trafficLights.size() ; i++) {
            if (trafficLights.get(i).getTrafficLightId().equalsIgnoreCase(trafficLightId)) {
                trafficLightLocation = intersections.get(i);
                break;
            }
        }
        return trafficLightLocation;
    }

    @Override
    public String getTrafficLightId() {
        return trafficLightId;
    }

    @Override
    public List<String> getControlledLanes(String pTrafficLightID) {
        return controller.getControlledLanes(pTrafficLightID);
    }

    @Override
    public List<String> getControlledEdges(String pTrafficLightId) {
        return controller.getControlledEdges(pTrafficLightId);
    }

    @Override
    public Map<RoadNetworkLink, TrafficLightState> getTrafficLightStateForEachLane() {
        return controller.getTrafficLightStateForEachLane(trafficLightId);
    }

    @Override
    public int getPhase(String pTrafficLightId) {
        return controller.getPhase(pTrafficLightId);
    }

    @Override
    public void setPhase(String pTrafficLightId, int phase) {
        controller.setPhase(pTrafficLightId, phase);
    }

    @Override
    public int getPhase() {
        return controller.getPhase(trafficLightId);
    }

    @Override
    public void setPhase(int phase) {
        controller.setPhase(trafficLightId, phase);
    }

    @Override
    public long getRemainingPhaseTime() {
        return controller.getRemainingPhaseTime(trafficLightId);
    }

    @Override
    public void setPhaseDuration(String trafficLightId, int extraTime) {
        controller.setPhaseDuration(trafficLightId, extraTime);
    }

    @Override
    public double getPhaseDuration(String trafficLightId) {
        return controller.getPhaseDuration(trafficLightId);
    }

    @Override
    public int getProgramId() {
        return controller.getProgramId(trafficLightId);
    }

    @Override
    public String getDefinition() {
        return controller.getDefinition(trafficLightId);
    }

    @Override
    public int getLastStepVehicleNumber(String edgeIdFrom) {
        return controller.getLastStepVehicleNumber(edgeIdFrom);
    }

    @Override
    public SumoTLSController getCompleteDefinition() {
        return controller.getCompleteDefinition(trafficLightId);
    }

    @Override
    public List<String> getLastStepVehicleIDs(String laneId) {
        return controller.getLastStepVehicleIDs(laneId);
    }

    @Override
    public double getVehicleSpeed(String vehicleId) {
        return controller.getVehicleSpeed(vehicleId);
    }

    @Override
    public Location getVehiclePosition(String vehicleId) {
        return controller.getVehiclePosition(vehicleId);
    }

    @Override
    public double getVehicleMaxSpeed(String vehicleId) {
        return controller.getVehicleMaxSpeed(vehicleId);
    }

    @Override
    public int getMinExpectedNumber() {
        return controller.getMinExpectedNumber();
    }

    @Override
    public int getEdgeOccupancyRate(String edgeIdFrom) {
        return controller.getEdgeOccupancyRate(edgeIdFrom);
    }

    @Override
    public void setCompleteRedYellowGreenDefinition(String trafficLightId, SumoTLSProgram sumoTLSProgram) {
        controller.setCompleteRedYellowGreenDefinition(trafficLightId, sumoTLSProgram);
    }

    @Override
    public boolean isValidTrafficLightId(String nextTL) {
        return controller.isValidTrafficLightId(nextTL);
    }

    @Override
    public double getRoadLength(String roadId) {
        return controller.getRoadLength(trafficLightId, roadId);
    }

    @Override
    public void setPhaseDuration(double timeExtension) {
        controller.setPhaseDuration(trafficLightId, timeExtension);
    }

    @Override
    public double getVehicleAcceleration(String vehicleId) {
        return controller.getVehicleAcceleration(vehicleId);
    }

    @Override
    public void initialize() {

    }

    @Override
    public void shutdown() {

    }

    @Override
    public Host getHost() {
        return host;
    }
}
