// Path: osgi.enroute.trains.api/src/osgi/enroute/trains/passenger/api/Person.java
// public class Person extends DTO {
// 
// 	public String id;
// 	
// 	public String firstName;
// 	public String lastName;
// 	
// 	public String email;
// 
// 	// urls to picture/website
// 	public String picture;
// 	public String website;
// 	
// 	// for "networking" applications?
// 	public String company;
// 	public String phone;
// 	
// }
// 
// Path: osgi.enroute.trains.api/src/osgi/enroute/trains/passenger/api/PersonDatabase.java
// public interface PersonDatabase {
// 
// 	Person register(String email, String firstName, String lastName);
// 	
// 	Person register(String email, String firstName, String lastName, String company, String phone, String picture, String website);
// 	
// 	List<Person> getPersons();
// 	
// 	Person getPerson(String id);
// 	
// }
// 
// Path: osgi.enroute.trains.api/src/osgi/enroute/trains/stations/api/Station.java
// public class Station extends DTO {
// 
// 	/**
// 	 * Name of the station
// 	 */
// 	public String name;
// 	
// 	/**
// 	 * Segment the station is located on
// 	 */
// 	public String segment;
// }
// 
// Path: osgi.enroute.trains.api/src/osgi/enroute/trains/stations/api/StationsManager.java
// public interface StationsManager {
// 
// 	/**
// 	 * List all known stations
// 	 * @return
// 	 */
// 	List<Station> getStations();
// 	
// 	/**
// 	 * Return the segment for this station
// 	 * @param station
// 	 * @return
// 	 */
// 	String getStationSegment(String station);
// 
// 	/**
// 	 * Return the station for this segment
// 	 */
// 	String getStation(String segment);
// 	
// 	/**
// 	 * List the passengers currently waiting in a station
// 	 * @param station
// 	 * @return
// 	 */
// 	List<Passenger> getPassengersWaiting(String station);
// 	
// 	/**
// 	 * List all passengers currently traveling on the train
// 	 * @param train
// 	 * @return
// 	 */
// 	List<Passenger> getPassengersOnTrain(String train);
// 	
// 	/**
// 	 * Person checks in at a station with a certain destination
// 	 * @param person
// 	 * @param station
// 	 * @param destination
// 	 */
// 	Passenger checkIn(String personId, String station, String destination);
// 
// 	/**
// 	 * Train calls unboard to let people hop off the train
// 	 * @param train
// 	 * @param station
// 	 */
// 	// rename to arrive
// 	void arrive(String train, String station);
// 	
// 	/**
// 	 * Train boards passengers at a given station
// 	 * @param train
// 	 * @param station
// 	 * @return the list of passengers that boarded the train (includes passengers that are still on the train)
// 	 */
// 	List<Passenger> leave(String train, String station);
// 	
// }


import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
import osgi.enroute.scheduler.api.Scheduler;
import osgi.enroute.trains.passenger.api.Person;
import osgi.enroute.trains.passenger.api.PersonDatabase;
import osgi.enroute.trains.stations.api.Station;
import osgi.enroute.trains.stations.api.StationsManager;
package osgi.enroute.trains.passengers.provider;




/**
 * Listens for checkins from events
 * 
 * Also randomly selects a persons to check in at a certain station
 * 
 * A person might be selected twice to check in at different stations ... in this case
 * the StationsManager should detect this and refuse these check-ins
 */
@Component(name = "osgi.enroute.trains.passengers", 
	property={"event.topics=osgi/trains/passengers/checkin"},
	immediate=true)
public class PassengersSimulator implements EventHandler {

	@Reference
	private Scheduler scheduler;
	
	@Reference
	private PersonDatabase personDB;
	
	@Reference
	private StationsManager stations;
	
	private Closeable tick;
	private Random r = new Random(System.currentTimeMillis());
	
	@Activate
	void activate() throws Exception{
		this.tick = scheduler.schedule(this::tick, 1000, 10000);
	}

	@Deactivate
	void deactivate() throws IOException {
		this.tick.close();
	}

	void tick() throws Exception {
		// randomly try to check in a passenger at a station
		try {
			Person p = personDB.getPersons().get(r.nextInt(personDB.getPersons().size()));
			
// Path: osgi.enroute.trains.api/src/osgi/enroute/trains/passenger/api/Person.java
// public class Person extends DTO {
// 
// 	public String id;
// 	
// 	public String firstName;
// 	public String lastName;
// 	
// 	public String email;
// 
// 	// urls to picture/website
// 	public String picture;
// 	public String website;
// 	
// 	// for "networking" applications?
// 	public String company;
// 	public String phone;
// 	
// }
// 
// Path: osgi.enroute.trains.api/src/osgi/enroute/trains/passenger/api/PersonDatabase.java
// public interface PersonDatabase {
// 
// 	Person register(String email, String firstName, String lastName);
// 	
// 	Person register(String email, String firstName, String lastName, String company, String phone, String picture, String website);
// 	
// 	List<Person> getPersons();
// 	
// 	Person getPerson(String id);
// 	
// }
// 
// Path: osgi.enroute.trains.api/src/osgi/enroute/trains/stations/api/Station.java
// public class Station extends DTO {
// 
// 	/**
// 	 * Name of the station
// 	 */
// 	public String name;
// 	
// 	/**
// 	 * Segment the station is located on
// 	 */
// 	public String segment;
// }
// 
// Path: osgi.enroute.trains.api/src/osgi/enroute/trains/stations/api/StationsManager.java
// public interface StationsManager {
// 
// 	/**
// 	 * List all known stations
// 	 * @return
// 	 */
// 	List<Station> getStations();
// 	
// 	/**
// 	 * Return the segment for this station
// 	 * @param station
// 	 * @return
// 	 */
// 	String getStationSegment(String station);
// 
// 	/**
// 	 * Return the station for this segment
// 	 */
// 	String getStation(String segment);
// 	
// 	/**
// 	 * List the passengers currently waiting in a station
// 	 * @param station
// 	 * @return
// 	 */
// 	List<Passenger> getPassengersWaiting(String station);
// 	
// 	/**
// 	 * List all passengers currently traveling on the train
// 	 * @param train
// 	 * @return
// 	 */
// 	List<Passenger> getPassengersOnTrain(String train);
// 	
// 	/**
// 	 * Person checks in at a station with a certain destination
// 	 * @param person
// 	 * @param station
// 	 * @param destination
// 	 */
// 	Passenger checkIn(String personId, String station, String destination);
// 
// 	/**
// 	 * Train calls unboard to let people hop off the train
// 	 * @param train
// 	 * @param station
// 	 */
// 	// rename to arrive
// 	void arrive(String train, String station);
// 	
// 	/**
// 	 * Train boards passengers at a given station
// 	 * @param train
// 	 * @param station
// 	 * @return the list of passengers that boarded the train (includes passengers that are still on the train)
// 	 */
// 	List<Passenger> leave(String train, String station);
// 	
// }


// Path: osgi.enroute.trains.passengers.provider/src/osgi/enroute/trains/passengers/provider/PassengersSimulator.java
import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
import osgi.enroute.scheduler.api.Scheduler;
import osgi.enroute.trains.passenger.api.Person;
import osgi.enroute.trains.passenger.api.PersonDatabase;
import osgi.enroute.trains.stations.api.Station;
import osgi.enroute.trains.stations.api.StationsManager;

package osgi.enroute.trains.passengers.provider;




/**
 * Listens for checkins from events
 * 
 * Also randomly selects a persons to check in at a certain station
 * 
 * A person might be selected twice to check in at different stations ... in this case
 * the StationsManager should detect this and refuse these check-ins
 */
@Component(name = "osgi.enroute.trains.passengers", 
	property={"event.topics=osgi/trains/passengers/checkin"},
	immediate=true)
public class PassengersSimulator implements EventHandler {

	@Reference
	private Scheduler scheduler;
	
	@Reference
	private PersonDatabase personDB;
	
	@Reference
	private StationsManager stations;
	
	private Closeable tick;
	private Random r = new Random(System.currentTimeMillis());
	
	@Activate
	void activate() throws Exception{
		this.tick = scheduler.schedule(this::tick, 1000, 10000);
	}

	@Deactivate
	void deactivate() throws IOException {
		this.tick.close();
	}

	void tick() throws Exception {
		// randomly try to check in a passenger at a station
		try {
			Person p = personDB.getPersons().get(r.nextInt(personDB.getPersons().size()));
			
			List<Station> s = stations.getStations();