/**
   * Check whether the vehicle can enter the intersection from a lane at the current time.
   *
   * @param laneId the id of the lane from which the vehicle enters the intersection.
   * @return whether the vehicle can enter the intersection
   */
  private boolean canEnterFromLane(int laneId) {
    Road road = Debug.currentMap.getRoad(laneId);

    double period = greenLightDuration + yellowLightDuration;
    int id = (int) Math.floor(basePolicy.getCurrentTime() / period);

    int phaseId = id % 4;

    boolean canPass = false;

    if (phaseId == 0) {
      canPass = road.getName().equals("1st Street W");
    } else if (phaseId == 1) {
      canPass = road.getName().equals("1st Avenue S");
    } else if (phaseId == 2) {
      canPass = road.getName().equals("1st Street E");
    } else if (phaseId == 3) {
      canPass = road.getName().equals("1st Avenue N");
    } else {
      throw new RuntimeException("Error in isGreenTrafficLightNow()");
    }

    if (canPass) {
      double t = basePolicy.getCurrentTime() - id * period;
      if (t <= greenLightDuration) {
        return true;
      } else {
        return false;
      }
    } else {
      // it is either yellow or red signal
      return false;
    }
  }
  /** {@inheritDoc} */
  @Override
  public void processRequestMsg(Request msg) {
    int vin = msg.getVin();

    // If the vehicle has got a reservation already, reject it.
    if (basePolicy.hasReservation(vin)) {
      basePolicy.sendRejectMsg(vin, msg.getRequestId(), Reject.Reason.CONFIRMED_ANOTHER_REQUEST);
      return;
    }

    // filter the proposals
    ProposalFilterResult filterResult =
        BasePolicy.standardProposalsFilter(msg.getProposals(), basePolicy.getCurrentTime());
    if (filterResult.isNoProposalLeft()) {
      basePolicy.sendRejectMsg(vin, msg.getRequestId(), filterResult.getReason());
    }

    List<Request.Proposal> proposals = filterResult.getProposals();

    // If cannot enter from lane according to canEnterFromLane(), reject it.
    if (!canEnterFromLane(proposals.get(0).getArrivalLaneID())) {
      basePolicy.sendRejectMsg(vin, msg.getRequestId(), Reject.Reason.NO_CLEAR_PATH);
      return;
    }
    // try to see if reservation is possible for the remaining proposals.
    ReserveParam reserveParam = basePolicy.findReserveParam(msg, proposals);
    if (reserveParam != null) {
      basePolicy.sendComfirmMsg(msg.getRequestId(), reserveParam);
    } else {
      basePolicy.sendRejectMsg(vin, msg.getRequestId(), Reject.Reason.NO_CLEAR_PATH);
    }
  }