/**
   * Displays a Discussion Thread page
   *
   * <p>- Requires a cookie for the session user - Requires a threadId request parameter for the
   * HTTP GET
   *
   * @param req The HTTP Request
   * @param res The HTTP Response
   */
  public void discussionAction(HttpServletRequest req, HttpServletResponse res) {
    // Ensure there is a cookie for the session user
    if (AccountController.redirectIfNoCookie(req, res)) return;

    Map<String, Object> viewData = new HashMap<>();

    if (req.getMethod() == HttpMethod.Get) {

      // Get the thread
      GroupManager gm = new GroupManager();
      int threadId = Integer.parseInt(req.getParameter("threadId"));
      DiscussionManager discussionManager = new DiscussionManager();
      DiscussionThread thread = discussionManager.getThread(threadId);
      thread.setGroup(gm.get(thread.getGroupId()));
      thread.setPosts(discussionManager.getPosts(threadId));

      // get documents for the thread
      DocumentManager docMan = new DocumentManager();
      viewData.put("documents", docMan.getDocumentsForThread(threadId));

      viewData.put("thread", thread);
      viewData.put("title", "Discussion: " + thread.getThreadName());
      view(req, res, "/views/group/DiscussionThread.jsp", viewData);
    } else {
      httpNotFound(req, res);
    }
  }
  /**
   * Retrieves all of the Discussion Threads associated with a Group Id
   *
   * @param groupId The Group Id to get Threads for
   * @return A List of Discussion Threads that belong to the Group
   */
  public List<DiscussionThread> getThreads(int groupId) {
    ArrayList<DiscussionThread> threads = new ArrayList<>();

    try {
      // Create a prepared statement
      PreparedStatement pstmt =
          conn.prepareStatement("SELECT * FROM DiscussionThreads WHERE GroupId = ?");

      // Set the required parameters and execute
      pstmt.setInt(1, groupId);
      ResultSet rs = pstmt.executeQuery();

      // Get the results and add to the list
      if (rs.isBeforeFirst()) {
        while (!rs.isAfterLast()) {
          DiscussionThread thread = DiscussionThread.fromResultSet(rs);
          if (thread != null) {
            threads.add(thread);
          }
        }
      }
    } catch (Exception e) {
      logger.log(Level.SEVERE, "SQL Error", e);
    }

    return threads;
  }
  /**
   * Creates a Discussion Thread in the database
   *
   * @param discussion The Discussion to insert
   */
  public void createDiscussion(DiscussionThread discussion) {
    try {
      // Create a prepared statement
      PreparedStatement pstmt =
          conn.prepareStatement(
              "INSERT INTO DiscussionThreads (GroupId, ThreadName)" + "VALUES (?, ?)",
              Statement.RETURN_GENERATED_KEYS);

      // Set the required parameters and execute
      pstmt.setInt(1, discussion.getGroupId());
      pstmt.setString(2, discussion.getThreadName());
      pstmt.executeUpdate();

      // Get the generated id
      ResultSet rs = pstmt.getGeneratedKeys();
      if (rs.next()) discussion.setId(rs.getInt(1));
    } catch (Exception e) {
      logger.log(Level.SEVERE, "SQL Error", e);
    }
  }
  /**
   * Retrieves a single thread based on its Id
   *
   * @param threadId The Id of the Thread
   * @return The Thread with the given Id
   */
  public DiscussionThread getThread(int threadId) {
    DiscussionThread thread = null;

    try {
      // Create a prepared statement
      PreparedStatement pstmt =
          conn.prepareStatement("SELECT * FROM DiscussionThreads WHERE Id = ?");

      // Set the required parameters and execute
      pstmt.setInt(1, threadId);
      ResultSet rs = pstmt.executeQuery();
      thread = DiscussionThread.fromResultSet(rs);
    } catch (Exception e) {
      logger.log(Level.SEVERE, "SQL Error", e);
    }

    return thread;
  }
  /**
   * Displays the Create Discussion page for a HTTP Get, or creates a Discussion Thread for a HTTP
   * Post
   *
   * <p>- Requires a cookie for the session user - Requires a groupId request parameter for a GET -
   * Requires a groupId and threadName request parameter for a POST - Requires a document request
   * part for a POST
   *
   * @param req The HTTP Request
   * @param res The HTTP Response
   */
  public void createDiscussionAction(HttpServletRequest req, HttpServletResponse res) {
    // Ensure there is a cookie for the session user
    if (AccountController.redirectIfNoCookie(req, res)) return;

    Map<String, Object> viewData = new HashMap<>();

    if (req.getMethod() == HttpMethod.Get) {
      viewData.put("title", "Create Discussion");
      viewData.put("groupId", req.getParameter("groupId"));

      view(req, res, "/views/group/CreateDiscussion.jsp", viewData);
      return;
    } else if (req.getMethod() == HttpMethod.Post) {
      // save discussion
      GroupManager groupMan = new GroupManager();
      DiscussionThread thread = new DiscussionThread();
      int groupId = Integer.parseInt(req.getParameter("groupId"));
      thread.setGroupId(groupId);
      thread.setGroup(groupMan.get(groupId));
      thread.setThreadName(req.getParameter("threadName"));

      DiscussionManager dm = new DiscussionManager();
      dm.createDiscussion(thread);

      try {
        Part documentPart = req.getPart("document");

        // if we have a document to upload
        if (documentPart.getSize() > 0) {
          String uuid = DocumentController.saveDocument(this.getServletContext(), documentPart);
          Document doc = new Document();
          doc.setDocumentName(getFileName(documentPart));
          doc.setDocumentPath(uuid);
          doc.setVersionNumber(1);
          doc.setThreadId(thread.getId());
          doc.setGroupId(thread.getGroupId());

          DocumentManager docMan = new DocumentManager();
          docMan.createDocument(doc);

          // Get uploading User
          HttpSession session = req.getSession();
          Session userSession = (Session) session.getAttribute("userSession");
          User uploader = userSession.getUser();

          // Create a notification to all in the group
          NotificationManager notificationMan = new NotificationManager();
          groupMan = new GroupManager();
          List<User> groupUsers = groupMan.getGroupUsers(groupId);

          for (User u : groupUsers) {
            Notification notification =
                new Notification(
                    u.getId(),
                    u,
                    groupId,
                    null,
                    "User " + uploader.getFullName() + " has uploaded a document",
                    "/document/document?documentId=" + doc.getId());

            notificationMan.createNotification(notification);
          }
        }
      } catch (Exception e) {
        logger.log(Level.SEVERE, "Document save error", e);
      }

      redirectToLocal(req, res, "/group/discussion/?threadId=" + thread.getId());
      return;
    }
    httpNotFound(req, res);
  }