public ExchangeAccumulator getExchangesInitiatedByUser(String userEmail) {
    List<DirectBookExchange> directExchangesForUser =
        bookExchangeDao.getDirectExchangesInitiatedByUser(userEmail);
    List<BookExchangeChain> exchangeChainsInitiatedByUser =
        bookExchangeDao.getExchangeChainsInitiatedByUser(userEmail);

    return new ExchangeAccumulator(directExchangesForUser, exchangeChainsInitiatedByUser)
        .sortByCreationDate();
  }
  public void rejectDirectExchange(String userEmail, int id) throws BookExchangeInternalException {
    DirectBookExchange directExchangeToReject =
        bookExchangeDao
            .getDirectBookExchange(id)
            .orElseThrow(() -> new BookExchangeInternalException("No exchange found"));
    directExchangeToReject.setOver(true);
    directExchangeToReject.setSuccessful(false);
    directExchangeToReject.setDateCompleted(LocalDateTime.now());

    bookExchangeDao.saveBookExchange(directExchangeToReject);
    notifyOtherExchangeParticipant(userEmail, directExchangeToReject);
  }
  public ExchangeAccumulator getExchangeRequestsReceivedByUser(String userEmail) {
    List<DirectBookExchange> directExchangesForUser =
        bookExchangeDao.getDirectExchangesOfferedToUser(userEmail);
    List<BookExchangeChain> exchangeChainsInitiatedByUser =
        bookExchangeDao
            .getExchangeChainsUserInvitedIn(userEmail)
            .stream()
            .map(exchangeChainRequest -> exchangeChainRequest.getParentExchangeChain())
            .collect(Collectors.toList());

    return new ExchangeAccumulator(directExchangesForUser, exchangeChainsInitiatedByUser)
        .sortByCreationDate();
  }
  public void acceptDirectExchange(String userEmail, int bookRequestedId, int exchangeId)
      throws BookExchangeInternalException {
    DirectBookExchange directBookExchange =
        bookExchangeDao
            .getDirectBookExchange(exchangeId)
            .orElseThrow(() -> new BookExchangeInternalException("No exchanges found"));
    Book bookRequestedInExchange =
        bookDao
            .getBookForId(bookRequestedId)
            .orElseThrow(() -> new BookExchangeInternalException("No book found"));

    updateBooksToInactive(bookRequestedInExchange, directBookExchange.getBookRequested());
    updateExchangeDetails(directBookExchange, bookRequestedInExchange);
    bookExchangeDao.saveBookExchange(directBookExchange);
    notificationsDao.saveNotification(
        new Notification.NotificationBuilder()
            .setMessage(exchangeAccepted)
            .setUserNotified(bookRequestedInExchange.getPostedBy())
            .setNotificationType(NotificationType.DIRECT_EXCHANGE_ACCEPTED)
            .setDateCreated(LocalDateTime.now())
            .build());
  }
  public void recordExchange(String initiatorEmail, ExchangeOrder exchangeOrder)
      throws BookExchangeInternalException {
    Book bookUnderOffer =
        bookDao
            .getBookPostedByUser(
                exchangeOrder.getBookUnderOffer(), exchangeOrder.getBookUnderOfferOwner())
            .orElseThrow(() -> new BookExchangeInternalException("Book under offer not found"));
    User exchangeInitiator =
        userDao
            .findUserByEmail(initiatorEmail)
            .orElseThrow(() -> new BookExchangeInternalException("No user found for email"));
    DirectBookExchange exchangeToRecord = buildBookExchange(bookUnderOffer, exchangeInitiator);

    bookExchangeDao.saveBookExchange(exchangeToRecord);
    addNewExchangeRequestNotification(
        bookUnderOffer.getPostedBy(), exchangeInitiator.getFullName(), exchangeToRecord);
  }