/**
  * Return the label value of the period based on {@link Date}. eg :: 22/12/2012 - Period : ONEYEAR
  * return 12;
  *
  * @param period {@link SearchPeriods}
  * @param pubDate {@link Date}
  * @return
  */
 private Integer getLabelDateValue(final SearchPeriods periodSelected, final Date pubDate) {
   Integer labelValue = null;
   if (periodSelected.equals(SearchPeriods.ONEYEAR)) { // return motnhs
     labelValue = DateUtil.getValueCurrentMonthOfTheYear(pubDate);
   } else if (periodSelected.equals(SearchPeriods.THIRTYDAYS)) { // return days
     labelValue = DateUtil.getValueCurrentDateOfTheMonths(pubDate);
   } else if (periodSelected.equals(SearchPeriods.TWENTYFOURHOURS)) { // return hours
     labelValue = DateUtil.getValueHourOfTheDay(pubDate);
   } else if (periodSelected.equals(SearchPeriods.SEVENDAYS)) { // return days
     labelValue = DateUtil.getValueCurrentDayOfTheWeek(pubDate);
   } else if (periodSelected.equals(SearchPeriods.ALLTIME)) { // return years
     labelValue = DateUtil.getValueCurrentYear(pubDate);
   }
   return labelValue;
 }
 /*
  * (non-Javadoc)
  * @see org.encuestame.core.service.imp.IStatisticsService#getTotalSocialLinksbyHashTagUsageAndDateRangeGraph(java.lang.String, org.encuestame.utils.enums.SearchPeriods, javax.servlet.http.HttpServletRequest)
  */
 public List<HashTagDetailStats> getTotalSocialLinksbyHashTagUsageAndDateRangeGraph(
     final String tagName, final SearchPeriods period, final HttpServletRequest request)
     throws EnMeSearchException {
   List<HashTagDetailStats> tagDetailStatsBySocial = new ArrayList<HashTagDetailStats>();
   List<ItemStatDetail> tpSocialSavePublishedDetail = new ArrayList<ItemStatDetail>();
   List<TweetPollSavedPublishedStatus> tpSavedPublished =
       new ArrayList<TweetPollSavedPublishedStatus>();
   if (period == null) {
     throw new EnMeSearchException("search params required.");
   } else {
     // Retrieve all tweetpolls by period
     final List<TweetPoll> tpolls =
         getTweetPollsByHashTag(tagName, null, null, TypeSearchResult.HASHTAG, period);
     for (TweetPoll tweetPoll : tpolls) {
       tpSavedPublished =
           getTweetPollDao()
               .getSocialLinksByTypeAndDateRange(
                   tweetPoll, null, null, TypeSearchResult.TWEETPOLL);
       tpSocialSavePublishedDetail.addAll(
           ConvertDomainBean.convertTweetPollSavedPublishedStatusListToItemDetailBean(
               tpSavedPublished));
     }
     this.removeDuplicatleItemOutOfRange(tpSocialSavePublishedDetail, period.toDays());
     tagDetailStatsBySocial =
         this.compareHashtagListGraph(tpSocialSavePublishedDetail, period, request);
     return tagDetailStatsBySocial;
   }
 }
 /**
  * @param itemList
  * @param period
  * @param request
  * @return
  * @throws EnMeSearchException
  */
 private List<HashTagDetailStats> compareList(
     final List<ItemStatDetail> itemList,
     final SearchPeriods period,
     final HttpServletRequest request)
     throws EnMeSearchException {
   Integer month = 0;
   Integer monthB;
   String rangeSubLabel = null;
   boolean existItemStatDetailLabel = false;
   List<HashTagDetailStats> tagDetailStatsCompare = new ArrayList<HashTagDetailStats>();
   // FIXME: It's limited only for dates in the same year, upgrade to accept dates for different
   // year.
   for (int i = 0; i < itemList.size(); i++) {
     Long countItems = 0L;
     monthB = this.getLabelDateValue(period, itemList.get(i).getDate());
     for (int j = 0; j < itemList.size(); j++) {
       month = this.getLabelDateValue(period, itemList.get(j).getDate());
       if (monthB == month) {
         countItems++;
       }
     }
     // check if the label exist previously
     existItemStatDetailLabel =
         checkLabelExistsHashTagDetailStat(tagDetailStatsCompare, monthB.toString());
     if (!existItemStatDetailLabel) {
       rangeSubLabel = this.getHashTagStatsDataRangeLabel(period.toString(), monthB, request);
       tagDetailStatsCompare.add(
           this.createTagDetailsStats(monthB.toString(), countItems, rangeSubLabel));
     }
   }
   return tagDetailStatsCompare;
 }
  /*
   * (non-Javadoc)
   *
   * @see org.encuestame.core.service.imp.IStatisticsService#
   * getTotalVotesbyHashTagUsageAndDateRangeGraph(java.lang.String,
   * org.encuestame.utils.enums.SearchPeriods,
   * javax.servlet.http.HttpServletRequest)
   */
  public List<HashTagDetailStats> getTotalVotesbyHashTagUsageAndDateRangeGraph(
      final String tagName, final SearchPeriods period, final HttpServletRequest request)
      throws EnMeSearchException {
    List<ItemStatDetail> tpResultsBean = new ArrayList<ItemStatDetail>();
    List<TweetPollResult> tpollResults = new ArrayList<TweetPollResult>();
    List<TweetPollSwitch> tpollsSwitch = new ArrayList<TweetPollSwitch>();
    List<HashTagDetailStats> tagDetailStatsByVotes = new ArrayList<HashTagDetailStats>();
    if (period == null) {
      throw new EnMeSearchException("search params required.");
    } else {

      final List<TweetPoll> tpolls =
          getTweetPollsByHashTag(tagName, null, null, TypeSearchResult.HASHTAG, period);
      log.debug("Total Tweetpolls by hashtagName" + tpolls.size());
      for (TweetPoll tweetPoll : tpolls) {
        tpollsSwitch = getTweetPollDao().getListAnswersByTweetPollAndDateRange(tweetPoll);
        log.trace("Total TweetpollSwitch by tweetPoll -->" + tpollsSwitch.size());
        for (TweetPollSwitch tweetPollSwitch : tpollsSwitch) {
          tpollResults = getTweetPollDao().getTweetPollResultsByTweetPollSwitch(tweetPollSwitch);
          log.trace("Total TweetPollResults by tweetPollSwitch -->" + tpollResults.size());
          tpResultsBean.addAll(
              ConvertDomainBean.convertTweetPollResultListToItemDetailBean(tpollResults));
        }
      }
    }
    this.removeDuplicatleItemOutOfRange(tpResultsBean, period.toDays());
    tagDetailStatsByVotes = this.compareHashtagListGraph(tpResultsBean, period, request);
    return tagDetailStatsByVotes;
  }
 /*
  * (non-Javadoc)
  * @see org.encuestame.core.service.imp.IStatisticsService#getTotalSocialLinksbyHashTagUsageAndDateRangeListGraph(java.lang.String, org.encuestame.utils.enums.SearchPeriods, javax.servlet.http.HttpServletRequest)
  */
 @Override
 public List<HashTagListGraphData> getTotalSocialLinksbyHashTagUsageAndDateRangeListGraph(
     String tagName, SearchPeriods period, HttpServletRequest request)
     throws EnMeSearchException, EnMeNoResultsFoundException {
   List<HashTagListGraphData> tagDetailStatsBySocial = new ArrayList<HashTagListGraphData>();
   List<ItemStatDetail> tpSocialSavePublishedDetail = new ArrayList<ItemStatDetail>();
   List<TweetPollSavedPublishedStatus> tpSavedPublished =
       new ArrayList<TweetPollSavedPublishedStatus>();
   if (period == null) {
     throw new EnMeSearchException("search params required.");
   } else {
     final List<TweetPoll> tpolls =
         getTweetPollsByHashTag(tagName, null, null, TypeSearchResult.HASHTAG, period);
     for (TweetPoll tweetPoll : tpolls) {
       final ItemStatDetail statDetail = new ItemStatDetail();
       tpSavedPublished =
           getTweetPollDao()
               .getSocialLinksByTypeAndDateRange(
                   tweetPoll, null, null, TypeSearchResult.TWEETPOLL);
       statDetail.setDate(tweetPoll.getCreateDate());
       statDetail.setItemId(Long.valueOf(tpSavedPublished.size()));
       // FIXME: itemId should be the id of something, now store a "total" value.
       // tpSocialSavePublishedDetail.addAll(ConvertDomainBean.convertTweetPollSavedPublishedStatusListToItemDetailBean(tpSavedPublished));
       tpSocialSavePublishedDetail.add(statDetail);
     }
     this.removeDuplicatleItemOutOfRange(tpSocialSavePublishedDetail, period.toDays());
     tagDetailStatsBySocial.addAll(
         this.groupListItemStatDetail(tpSocialSavePublishedDetail, period, request));
     return tagDetailStatsBySocial;
   }
 }
 /**
  * Get hashTags button stats.
  *
  * @param tagName
  * @param filter
  * @param limit
  * @param request
  * @param response
  * @return
  * @throws JsonGenerationException
  * @throws JsonMappingException
  * @throws IOException
  */
 @RequestMapping(value = "/api/common/hashtags/stats/button.json", method = RequestMethod.GET)
 public @ResponseBody ModelMap getHashTagButtonStats(
     @RequestParam(value = "tagName", required = true) String tagName,
     @RequestParam(value = "filter", required = true) String filter,
     @RequestParam(value = "period", required = false) String period,
     HttpServletRequest request,
     HttpServletResponse response)
     throws JsonGenerationException, JsonMappingException, IOException {
   try {
     final Map<String, Object> jsonResponse = new HashMap<String, Object>();
     final HashTagStatsBean tagStatsBean = new HashTagStatsBean();
     final TypeSearchResult filterType = TypeSearchResult.getTypeSearchResult(filter);
     final SearchPeriods searchPeriod = SearchPeriods.getPeriodString(period);
     if (filterType == null) {
       throw new EnMeNoResultsFoundException("type not found");
     } else {
       if (filterType.equals(TypeSearchResult.HASHTAGRATED)) {
         // hits /period
         tagStatsBean.setTotalHits(
             getStatisticsService()
                 .getHashTagHitsbyName(tagName, filterType, request, searchPeriod));
         tagStatsBean.getTotalHits().setTypeSearchResult(TypeSearchResult.HITS);
         // social network use /period
         tagStatsBean.setTotalUsageBySocialNetwork(
             getStatisticsService()
                 .getSocialNetworkUseByHashTag(
                     tagName, this.INIT_RESULTS, null, request, searchPeriod));
         tagStatsBean
             .getTotalUsageBySocialNetwork()
             .setTypeSearchResult(TypeSearchResult.SOCIALNETWORK);
         // usage by / period
         tagStatsBean.setUsageByItem(
             getStatisticsService()
                 .getTotalUsageByHashTag(
                     tagName, this.INIT_RESULTS, null, filterType, request, searchPeriod));
         tagStatsBean.getUsageByItem().setTypeSearchResult(TypeSearchResult.HASHTAG);
         // votes
         tagStatsBean.setUsageByVotes(
             getStatisticsService()
                 .getHashTagUsedOnItemsVoted(
                     tagName, this.INIT_RESULTS, null, request, searchPeriod));
         tagStatsBean.getUsageByVotes().setTypeSearchResult(TypeSearchResult.VOTES);
         jsonResponse.put("hashTagButtonStats", tagStatsBean);
         setItemResponse(jsonResponse);
       } else {
         setError("filter not valid", response);
       }
     }
   } catch (Exception e) {
     e.printStackTrace();
     log.error(e);
     setError(e.getMessage(), response);
   }
   return returnData();
 }
 /*
  * (non-Javadoc)
  *
  * @see org.encuestame.core.service.imp.IStatisticsService#
  * getTotalHitsUsagebyHashTagAndDateRange(java.lang.String,
  * java.lang.Integer, javax.servlet.http.HttpServletRequest)
  */
 public List<HashTagDetailStats> getTotalHitsUsagebyHashTagAndDateRange(
     final String hashTagName, final SearchPeriods period, final HttpServletRequest request)
     throws EnMeNoResultsFoundException, EnMeSearchException {
   List<Hit> hashTagHits = new ArrayList<Hit>();
   List<HashTagDetailStats> tagDetailStatsByHits = new ArrayList<HashTagDetailStats>();
   final HashTag tag = this.getHashTag(hashTagName, Boolean.TRUE);
   List<ItemStatDetail> itemStatDetailByHits = new ArrayList<ItemStatDetail>();
   if (tag != null) {
     hashTagHits = getFrontEndDao().getHashTagHitsbyDateRange(tag.getHashTagId(), period.toDays());
   }
   itemStatDetailByHits.addAll(ConvertDomainBean.convertHitListToItemDetailBean(hashTagHits));
   tagDetailStatsByHits = this.compareList(itemStatDetailByHits, period, request);
   return tagDetailStatsByHits;
 }
 /**
  * @param tagName
  * @param period
  * @param filter
  * @param request
  * @param response
  * @return
  */
 @RequestMapping(
     value = "/api/common/hashtags/stats/button/range.json",
     method = RequestMethod.GET)
 public @ResponseBody ModelMap getHashTagButtonStatsByDateRange(
     @RequestParam(value = "tagName", required = true) String tagName,
     @RequestParam(value = "period", required = false) String period,
     @RequestParam(value = "filter", required = true) String filter,
     HttpServletRequest request,
     HttpServletResponse response) {
   try {
     List<HashTagDetailStats> tagStats = new ArrayList<HashTagDetailStats>();
     final TypeSearchResult filterType = TypeSearchResult.getTypeSearchResult(filter);
     // final SearchPeriods periodSearch = SearchPeriods.getPeriodString(period);
     final Map<String, Object> jsonResponse = new HashMap<String, Object>();
     final SearchPeriods searchPeriods = SearchPeriods.getPeriodString(period);
     if (searchPeriods == null) {
       setError("Period not valid", response);
     } else {
       if (filterType.equals(TypeSearchResult.HASHTAG)) {
         tagStats =
             getStatisticsService()
                 .getTotalUsagebyHashtagAndDateRangeGraph(tagName, searchPeriods, request);
       } else if (filterType.equals(TypeSearchResult.SOCIALNETWORK)) {
         tagStats =
             getStatisticsService()
                 .getTotalSocialLinksbyHashTagUsageAndDateRangeGraph(
                     tagName, searchPeriods, request);
       } else if (filterType.equals(TypeSearchResult.HITS)) {
         tagStats =
             getStatisticsService()
                 .getTotalHitsUsagebyHashTagAndDateRangeGraph(tagName, searchPeriods, request);
       } else if (filterType.equals(TypeSearchResult.VOTES)) {
         tagStats =
             getStatisticsService()
                 .getTotalVotesbyHashTagUsageAndDateRangeGraph(tagName, searchPeriods, request);
       }
       jsonResponse.put("statsByRange", tagStats);
       setItemResponse(jsonResponse);
     }
   } catch (Exception e) {
     e.printStackTrace();
     log.error(e);
     setError(e.getMessage(), response);
   }
   return returnData();
 }
  /**
   * Return total votes by tweetpoll filtered by hashtag.
   *
   * @param tagName
   * @param period
   * @return
   */
  private Long retrieveTweetPollTotalVotesByHashTag(
      final String tagName, final SearchPeriods period) {
    Long totalTweetPollVotes = 0L;
    // 1- Retrieve a tweetpoll list filtered by hashtag and specific period
    final List<TweetPoll> tweetPolls =
        this.getTweetPollsByHashTag(tagName, null, null, TypeSearchResult.HASHTAG, period);

    log.debug(
        "TweetPolls by HashTag ****************************************** "
            + tweetPolls.size()
            + "Period ***********************"
            + period.toString());
    // 2-  Iterate tweetpoll list and sum of votes for each tweetpoll
    for (TweetPoll tweetPoll : tweetPolls) {
      final Long votesByTweetPoll =
          getTweetPollDao().getTotalVotesByTweetPollId(tweetPoll.getTweetPollId());

      totalTweetPollVotes = totalTweetPollVotes + votesByTweetPoll.intValue();
    }
    log.debug(
        "Total Votes by Tweetpoll ******************************************"
            + totalTweetPollVotes);
    return totalTweetPollVotes;
  }
  /**
   * Convert a number to correct i18n label. eg: 12 == December / ONEYEAR 6 == Saturday / SEVENDAYS
   * 24 == 24 / TWENTYFOURHOURS
   *
   * @param period the period
   * @param label the label to be translated
   * @param request {@link HttpServletRequest}.
   * @return
   */
  private String getHashTagStatsDataRangeLabel(
      final String period, final Integer label, final HttpServletRequest request) {
    String dataRangeLabel = null;
    HashTagRate tagRateLabel;
    final SearchPeriods periodSelected = SearchPeriods.getPeriodString(period);

    if (periodSelected.equals(SearchPeriods.ONEYEAR)) {
      tagRateLabel = HashTagRate.getHashTagMonthLabel(Integer.toString(label));
      dataRangeLabel =
          this.convertHashTagDataRangeLabelMessage(tagRateLabel, request, new Object[] {});
    } else if (periodSelected.equals(SearchPeriods.ALLTIME)) {
      dataRangeLabel = String.valueOf(label);
    } else if (periodSelected.equals(SearchPeriods.THIRTYDAYS)) {
      dataRangeLabel = String.valueOf(label);
    } else if (periodSelected.equals(SearchPeriods.TWENTYFOURHOURS)) {
      dataRangeLabel = String.valueOf(label);
    } else if (periodSelected.equals(SearchPeriods.SEVENDAYS)) {
      tagRateLabel = HashTagRate.getHashTagWeekDayLabel(Integer.toString(label));
      dataRangeLabel =
          this.convertHashTagDataRangeLabelMessage(tagRateLabel, request, new Object[] {});
    }
    return dataRangeLabel;
  }
  /**
   * @api {get} /api/common/geolocation/search/{typeOfSearch}.json Get Items by Geolocation
   * @apiVersion 1.0.0
   * @apiName GetGeoItemsByType
   * @apiGroup Geolocation
   * @apiPermission user
   * @apiDescription A tag cloud of hashtags with the top hashtags in post mentioning ordered by
   *     frecuency.
   * @apiParam {Number} range
   * @apiParam {Number} maxItem
   * @apiParam {String} type
   * @apiParam {Number} longitude
   * @apiParam {Number} latitude
   * @apiParam {Number} period
   * @apiParam {String} tagName
   * @apiParam {String} typeOfSearch
   * @apiSampleRequest http://www.encuestame.org/demo/api/common/geolocation/search/tweetpoll.json
   * @apiSuccessExample
   * @apiSuccess {Object} success
   * @apiSuccess {String} error
   */
  @RequestMapping(
      value = "/api/common/geolocation/search/{typeOfSearch}.json",
      method = RequestMethod.GET)
  public @ResponseBody ModelMap getItemsbyGeoLocationRange(
      @RequestParam(value = "range", required = true) Double range,
      @RequestParam(value = "maxItem", required = true) Integer maxItem,
      @RequestParam(value = "type", required = true) String type,
      @RequestParam(value = "longitude", required = true) Double longitude,
      @RequestParam(value = "latitude", required = true) Double latitude,
      @RequestParam(value = "period", required = true) String period,
      @RequestParam(value = "tag", required = false) String tagName,
      @PathVariable final String typeOfSearch,
      HttpServletRequest request,
      HttpServletResponse response)
      throws JsonGenerationException, JsonMappingException, IOException {

    try {
      log.debug("Range " + range);
      log.debug("Maximum " + maxItem);

      SearchPeriods periodValue =
          (period.isEmpty() ? SearchPeriods.ALLTIME : SearchPeriods.getPeriodString(period));
      TypeSearchResult typeValue =
          (type.isEmpty() ? TypeSearchResult.ALL : TypeSearchResult.getTypeSearchResult(type));
      TypeSearchResult searchType = TypeSearchResult.getTypeSearchResult(typeOfSearch);
      List<ItemGeoLocationBean> itemsByLocation = new ArrayList<ItemGeoLocationBean>();
      final Map<String, Object> jsonResponse = new HashMap<String, Object>();
      if (searchType.equals(TypeSearchResult.ALL)) {
        itemsByLocation =
            getLocationService()
                .retrieveItemsByGeo(range, maxItem, typeValue, longitude, latitude, periodValue);
        log.debug("Items by geo location " + itemsByLocation.size());
        jsonResponse.put("itemsByGeo", itemsByLocation);
      } else if (searchType.equals(TypeSearchResult.HASHTAG)) {
        if (tagName == null) {
          throw new EnMeSearchException("search params required.");
        } else {

          itemsByLocation =
              getLocationService()
                  .retreiveHashTagUsebyGeoLo(
                      range, maxItem, typeValue, longitude, latitude, tagName, periodValue);
          log.debug("Hashtag use by geo location " + itemsByLocation.size());
          jsonResponse.put("hashtagUsebyGeo", itemsByLocation);
        }

      } else if (searchType.equals(TypeSearchResult.SOCIALNETWORK)) {
        itemsByLocation =
            getLocationService()
                .retrieveSocialNetworksPublicationsbyGeoLocation(
                    range, maxItem, typeValue, longitude, latitude, periodValue);
        log.debug("Social publications  by geo location " + itemsByLocation.size());
        jsonResponse.put("socialGeo", itemsByLocation);
      }
      setItemResponse(jsonResponse);

    } catch (Exception e) {
      log.error(e);
      setError(e.getMessage(), response);
    }
    return returnData();
  }