// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_HISTORY_VISIT_FILTER_H_
#define CHROME_BROWSER_HISTORY_VISIT_FILTER_H_

#include <vector>

#include "base/gtest_prod_util.h"
#include "base/time/time.h"

namespace history {

class VisitRow;

// Helper class for creation of filters for VisitDatabase that is used to filter
// out visits by time of the day, day of the week, workdays, holidays, duration
// of the visit, location and the combinations of that.
// It also stores sorting order of the returned resilts.
class VisitFilter {
 public:
  VisitFilter();
  virtual ~VisitFilter();

  // Vector of time intervals [begin time, end time]. All of the following
  // functions produce vectors that are sorted in order from most recent to
  // least recent and have intervals that do not intersect.
  // |first| always points to the beginning of the time period, |second| - to
  // the end.
  typedef std::vector<std::pair<base::Time, base::Time> > TimeVector;

  // Returns time vector associated with the object.
  const TimeVector& times() const {
    return times_;
  }

  // Sets |max_results| of the results to be returned. 0 means "return results
  // for the two months prior to passed time".
  void set_max_results(size_t max_results) {
    max_results_ = max_results;
    if (times_.size() > max_results_)
      times_.resize(max_results_);
  }

  // Sets the time that should be used as a basis for the filter. Normally this
  // is the time that a query is made.
  void SetFilterTime(const base::Time& filter_time);

  // Sets the amount of time around the filter time to take into account. This
  // only applies to the filter time's time-of-day, restrictions on how long
  // back in time to look should be controlled by changing |max_results|.
  //
  // How the filter width is used depends on the sorting order. For
  // |ORDER_BY_TIME_LINEAR| it is the distance to the cutoff point, while for
  // |ORDER_BY_TIME_GAUSSIAN| it is the standard deviation.
  void SetFilterWidth(const base::TimeDelta& filter_width);

  // The following two filters are exclusive - setting one, clears the other
  // one.

  // Sets the filter to use only visits that happened on the specified day of
  // the week.
  // |day| - day of the week: 0 - sunday, 1 - monday, etc.
  void SetDayOfTheWeekFilter(int day);

  // Sets the filter to use only visits that happened on a holiday/workday.
  // |workday| - if true means Monday-Friday, if false means Saturday-Sunday.
  // TODO(georgey) - internationalize it.
  void SetDayTypeFilter(bool workday);

  // Sorting order that results after applying this filter are sorted by.
  enum SortingOrder {
    ORDER_BY_RECENCY,  // Most recent visits are most relevant ones. (default)
    ORDER_BY_VISIT_COUNT,  // Most visited are listed first.
    ORDER_BY_DURATION_SPENT,  // The sites that user spents more time in are
                              // sorted first.
    ORDER_BY_TIME_GAUSSIAN,  // Visits that happened closer to the filter time's
                             // time-of-day are scored higher. The dropoff in
                             // score follows a normal distribution curve with
                             // the filter width as the standard deviation.
    ORDER_BY_TIME_LINEAR,  // Visits that happened closer to the filter time's
                           // time-of-day are score higher. The dropoff in score
                           // is a linear function, with filter width being the
                           // point where a visit does not count at all anymore.
  };

  double GetVisitScore(const VisitRow& visit) const;

  void set_sorting_order(SortingOrder order) {
    sorting_order_ = order;
    UpdateTimeVector();
  }

  SortingOrder sorting_order() const {
    return sorting_order_;
  }

  // Clears all of the filters.
  void ClearFilters();

 private:
  FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, CheckFilters);
  FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, GetTimesInRange);
  FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, GetTimesOnTheDayOfTheWeek);
  FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, GetTimesOnTheSameDayType);
  FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, UniteTimeVectors);
  FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, IntersectTimeVectors);

  // Internal helper for the update.
  bool UpdateTimeVector();

  // Internal helper for getting the times in range. See SetTimeInRangeFilter().
  static void GetTimesInRange(base::Time begin_time_of_the_day,
                              base::Time end_time_of_the_day,
                              size_t max_results,
                              TimeVector* times);

  // Internal helper for getting the days in range. See SetDayOfTheWeekFilter().
  // |day| could be outside of the range: -4 (3 - 7) means Wednesday last week,
  // 17 (3 + 2 * 7) means Wednesday in two weeks.
  static void GetTimesOnTheDayOfTheWeek(int day,
                                        base::Time week,
                                        size_t max_results,
                                        TimeVector* times);

  // Internal helper for getting the days in range. See SetDayTypeFilter().
  static void GetTimesOnTheSameDayType(bool workday,
                                       base::Time week,
                                       size_t max_results,
                                       TimeVector* times);

  // Unites two vectors, so the new vector has non-intersecting union of the
  // original ranges. Returns true if the result is non-empty, false otherwise.
  static bool UniteTimeVectors(const TimeVector& vector1,
                               const TimeVector& vector2,
                               TimeVector* result);

  // Intersects two vectors, so the new vector has ranges that are covered by
  // both of the original ranges. Returns true if the result is non-empty, false
  // otherwise.
  static bool IntersectTimeVectors(const TimeVector& vector1,
                                   const TimeVector& vector2,
                                   TimeVector* result);

  // Returns the time-of-day difference between the two times. The result will
  // always represent a value between 0 and 12 hours inclusive.
  static base::TimeDelta GetTimeOfDayDifference(base::Time t1, base::Time t2);

  base::Time filter_time_;
  base::TimeDelta filter_width_;
  enum {
    DAY_UNDEFINED = -1,
    WORKDAY = 7,
    HOLIDAY = 8,
  };
  int day_;
  TimeVector times_;
  size_t max_results_;
  SortingOrder sorting_order_;
};

}  // history

#endif  // CHROME_BROWSER_HISTORY_VISIT_FILTER_H_
