package elevator;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import common.Direction;

/**
 * Class to represent the requests that need to be sent once an elevator reaches
 * a certain floor
 */
public class ElevatorRequestFloorQueue {

	/**
	 * Structure that is a map of floors. Each floor has another map of Direction to
	 * sort the requests by direction. Each direction contains a set of floor
	 * numbers that "users" will request
	 */
	private Map<Integer, Map<Direction, Set<Integer>>> floorQueue;

	/**
	 * Create an elevator request queue which is used to simulate users in an
	 * elevator pressing floor buttons to go to
	 *
	 * @param numFloors
	 */
	public ElevatorRequestFloorQueue(int numFloors) {
		floorQueue = new HashMap<>();

		for (int i = 1; i <= numFloors; i++) {
			Map<Direction, Set<Integer>> floorRequestSets = new HashMap<>();
			floorRequestSets.put(Direction.UP, new HashSet<Integer>());
			floorRequestSets.put(Direction.DOWN, new HashSet<Integer>());
			floorQueue.put(i, floorRequestSets);
		}
	}

	/**
	 * Add the specified request floor to the proper floor queue
	 *
	 * @param inputFloor   the floor the request is being made from
	 * @param direction    direction
	 * @param requestFloor the requested floor to go to
	 */
	public void addRequest(int inputFloor, Direction direction, int requestFloor) {
		floorQueue.get(inputFloor).get(direction).add(requestFloor);
	}

	/**
	 * Check if the floor queue has any requests
	 *
	 * @param inputFloor
	 * @param direction
	 * @return true if there are requests
	 */
	public boolean checkNextFloorRequest(int inputFloor, Direction direction) {
		if (direction != null) {
			Set<Integer> floorVisitSet = floorQueue.get(inputFloor).get(direction);

			return !floorVisitSet.isEmpty();
		}
		return false;
	}

	/**
	 * Get the floor requests from the specified floor and direction queue
	 *
	 * @param inputFloor the floor the request originates from
	 * @param direction  the direction queue to check
	 * @return all floor requests in the specified direction
	 */
	public Set<Integer> getNextFloorRequests(int inputFloor, Direction direction) {
		if (direction != null) {
			Set<Integer> requestFloors = floorQueue.get(inputFloor).get(direction);

			// Clear the floor requests from the specified floor and direction queue
			floorQueue.get(inputFloor).put(direction, new HashSet<Integer>());

			return requestFloors;
		}
		return null;
	}
}
