/**
   * Get Web Service for getting adverts that a member has searched for using words or phrases.
   *
   * @param tags - String representing the words or phrases entered into search.
   * @return - Server response indicating success or failure with a message.
   */
  @GET
  @Path("{tags}")
  public Response getSearchedAdverts(@PathParam("tags") String tags) {
    if (tags == null) {
      return Response.serverError().entity("Tags cannot be blank").build();
    }
    List<Advert> adsList = new ArrayList<>();
    DBConnector db = new DBConnector();
    try {
      db.createConnection();
      adsList = db.getSearchedForAdverts(URLDecoder.decode(tags, "UTF-8"));
      db.closeConnection();
    } catch (SQLException | ClassNotFoundException | UnsupportedEncodingException ex) {
      Logger.getLogger(GetSearchAdvertsREST.class.getName()).log(Level.SEVERE, null, ex);
    }
    if (adsList.isEmpty()) {
      return Response.status(Response.Status.NOT_FOUND)
          .entity("No adverts found with search terms: " + tags)
          .build();
    }
    String json = new Gson().toJson(adsList);

    return Response.ok(json, MediaType.APPLICATION_JSON).build();
  }
  /**
   * On each web service call this method is run to authenticate that the caller is allowed to
   * retrieve the data related to the call.
   *
   * @param request The servlet request we are processing
   * @param response The servlet response we are creating
   * @param chain The filter chain we are processing
   * @exception IOException if an input/output error occurs
   * @exception ServletException if a servlet error occurs
   */
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {

    if (debug) {
      log("AuthenticationFilter:doFilter()");
    }

    // Test whether TLS is in operation.
    // System.out.println(request.isSecure());
    doBeforeProcessing(request, response);
    Throwable problem = null;

    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;

    // Don't authenticate when any of these web services are called.
    String requestUrl = req.getRequestURL().toString();
    if (requestUrl.contains("memberpassword")
        || requestUrl.contains("registermember")
        || requestUrl.contains("advertimagesbyid")
        || requestUrl.contains("advertbyid")
        || requestUrl.contains("currentadverts")
        || requestUrl.contains("searchadverts")
        || requestUrl.contains("allrules")) {
      try {
        chain.doFilter(request, response);
      } catch (Throwable t) {
        // If an exception is thrown somewhere down the filter chain,
        // we still want to execute our after processing, and then
        // rethrow the problem after that.
        problem = t;
        t.printStackTrace();
      }
    } else {
      // Decode the data back to original string
      try {

        String decoded;

        // Get the Authorisation Header from Request
        String header = req.getHeader("Authorization");

        // Header is in the format "Basic 3nc0dedDat4"
        // We need to extract data before decoding it back to original string
        String data = header.substring(header.indexOf(" ") + 1);

        byte[] bytes = Base64.getDecoder().decode(data);
        decoded = new String(bytes);
        String[] array = decoded.split(":");

        if (!array[0].isEmpty() && !array[1].isEmpty()) {
          String hashPass = "";
          DBConnector db = new DBConnector();
          try {
            db.createConnection();
            hashPass = db.getMemberPassword(array[0]);
            db.closeConnection();
          } catch (SQLException | ClassNotFoundException ex) {
            Logger.getLogger(AuthenticationFilter.class.getName()).log(Level.SEVERE, null, ex);
          }
          if (!"".equals(hashPass)) {
            if (hashPass.equals(array[1])) {
              try {
                chain.doFilter(request, response);
              } catch (Throwable t) {
                // If an exception is thrown somewhere down the filter chain,
                // we still want to execute our after processing, and then
                // rethrow the problem after that.
                problem = t;
                t.printStackTrace();
              }
            } else {
              res.sendError(javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED);
            }
          } else {
            res.sendError(javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE);
          }
        } else {
          res.sendError(javax.servlet.http.HttpServletResponse.SC_NOT_ACCEPTABLE);
        }
      } catch (Exception ex) {
        res.sendError(javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED);
      }
    }

    doAfterProcessing(request, response);

    // If there was a problem, we want to rethrow it if it is
    // a known type, otherwise log it.
    if (problem != null) {
      if (problem instanceof ServletException) {
        throw (ServletException) problem;
      }
      if (problem instanceof IOException) {
        throw (IOException) problem;
      }
      sendProcessingError(problem, response);
    }
  }