/**
   * Commit seats held for a specific customer
   *
   * @param seatHoldId the seat hold identifier
   * @param customerEmail the email address of the customer to which the seat hold is assigned
   * @return a reservation confirmation code
   */
  @Override
  public String reserveSeats(int seatHoldId, String customerEmail) {
    // Before proceeding with reservation, make sure holds are not expired.
    resetHolds();

    // NOW proceed with reservation logic.
    Map<String, List<SeatHoldVO>> seatsOnHold = TemporaryDatabase.getSeatsOnHold();
    int failureCnt = 0;
    if (seatsOnHold != null && !seatsOnHold.isEmpty()) {
      List<SeatHoldVO> seatHoldList = seatsOnHold.get(customerEmail);
      if (seatHoldList != null && !seatHoldList.isEmpty()) {
        Iterator<SeatHoldVO> seatHoldIter = seatHoldList.iterator();
        while (seatHoldIter.hasNext()) {
          SeatHoldVO seatHold = seatHoldIter.next();
          if (seatHold != null && seatHold.getSeatHoldId() == seatHoldId) {
            List<SeatInfoVO> seatsList = seatHold.getSeatsList();
            if (seatsList != null && !seatsList.isEmpty()) {
              Iterator<SeatInfoVO> seatInfoIter = seatsList.iterator();
              while (seatInfoIter.hasNext()) {
                SeatInfoVO seatInfo = seatInfoIter.next();
                boolean reserveStatus =
                    processSeatReserve(
                        seatInfo.getLevelNum(), seatInfo.getRowNum(), seatInfo.getSeatNum());
                if (!reserveStatus) {
                  failureCnt++;
                }
                seatInfoIter.remove();
              }
              seatHoldIter.remove();
            } else {
              // WE are about to reserve seats, but seats are EMPTY, which means failure.
              failureCnt++;
            }
          }
        }
      } else {
        // WE are about to reserve seats, but seats are EMPTY, which means failure.
        failureCnt++;
      }
    }
    if (failureCnt > 0) {
      return Constants.FAILURE_MSG;
    }
    return Constants.SUCCES_MSG;
  }
  /**
   * This method updates temporary database maps hold status to AVAILABLE, if Hold expired after 10
   * seconds.
   */
  private void resetHolds() {
    // Reset Holds on Levels
    List<LevelVO> levels = TemporaryDatabase.getStage();
    for (LevelVO levelVO : levels) {
      if (levelVO != null) {
        Map<Integer, List<SeatVO>> rowsAndSeats = levelVO.getRowsAndSeats();
        Set<Integer> rows = rowsAndSeats.keySet();
        if (rows != null && !rows.isEmpty()) {
          for (Integer row : rows) {
            List<SeatVO> seats = rowsAndSeats.get(row);
            if (seats != null && !seats.isEmpty()) {
              for (SeatVO seatVO : seats) {
                if (seatVO != null && seatVO.getStatusCode() == Constants.SEAT_HOLD) {
                  if (!holdNotExpired(seatVO.getHoldTimeStamp().getTime())) {
                    // Update stauts code to available
                    seatVO.setStatusCode(Constants.SEAT_AVAILABLE);
                  }
                }
              }
            }
          }
        }
      }
    }

    // Reset Holds on HoldsAndSeats
    Map<String, List<SeatHoldVO>> holds = TemporaryDatabase.getSeatsOnHold();
    if (holds != null && !holds.isEmpty()) {
      Collection<List<SeatHoldVO>> seatHolds = holds.values();
      if (seatHolds != null && !seatHolds.isEmpty()) {
        for (List<SeatHoldVO> seatHoldList : seatHolds) {
          if (seatHoldList != null && !seatHoldList.isEmpty()) {
            Iterator<SeatHoldVO> seatHoldIter = seatHoldList.iterator();
            while (seatHoldIter.hasNext()) {
              SeatHoldVO seatHold = seatHoldIter.next();
              if (seatHold != null
                  && seatHold.getSeatsList() != null
                  && !seatHold.getSeatsList().isEmpty()) {
                Iterator<SeatInfoVO> seatInfoIter = seatHold.getSeatsList().iterator();
                while (seatInfoIter.hasNext()) {
                  SeatInfoVO seatInfo = seatInfoIter.next();
                  if (!holdNotExpired(seatInfo.getHoldTimeStamp().getTime())) {
                    seatInfoIter.remove();
                  }
                }
              }

              if (seatHold != null && seatHold.getSeatsList().isEmpty()) {
                seatHoldIter.remove();
              }
            }
          }
        }
      }
    }

    //        Map<String, List<SeatHoldVO>> resetHolds = TemporaryDatabase.getSeatsOnHold();
    //        if (resetHolds != null && !resetHolds.isEmpty()) {
    //            Collection<List<SeatHoldVO>> seatHolds = resetHolds.values();
    //            Iterator<List<SeatHoldVO>> seatIter = seatHolds.iterator();
    //            while (seatIter.hasNext()) {
    //                List<SeatHoldVO> seatholdList = seatIter.next();
    //                if (seatholdList != null && !seatholdList.isEmpty()) {
    //                    Iterator<SeatHoldVO> seatholdIter = seatholdList.iterator();
    //                    while (seatholdIter.hasNext()) {
    //
    //                    }
    //                }
    //            }
    //        }

  }