// 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_DOWNLOAD_DOWNLOAD_QUERY_H_
#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_QUERY_H_

#include <map>
#include <string>
#include <vector>

#include "base/callback_forward.h"
#include "content/public/browser/download_item.h"

namespace base {
class Value;
}

// Filter and sort a vector of DownloadItem*s.
//
// The following example copies from |all_items| to |results| those
// DownloadItem*s whose start time is 0 and whose id is odd, sorts primarily by
// bytes received ascending and secondarily by url descending, and limits the
// results to 20 items. Any number of filters or sorters is allowed. If all
// sorters compare two DownloadItems equivalently, then they are sorted by their
// id ascending.
//
// DownloadQuery query;
// scoped_ptr<base::Value> start_time(base::Balue::CreateIntegerValue(0));
// CHECK(query.AddFilter(FILTER_START_TIME, *start_time.get()));
// bool FilterOutOddDownloads(const DownloadItem& item) {
//   return 0 == (item.GetId() % 2);
// }
// CHECK(query.AddFilter(base::Bind(&FilterOutOddDownloads)));
// query.AddSorter(SORT_BYTES_RECEIVED, ASCENDING);
// query.AddSorter(SORT_URL, DESCENDING);
// query.Limit(20);
// DownloadVector all_items, results;
// query.Search(all_items.begin(), all_items.end(), &results);
class DownloadQuery {
 public:
  typedef std::vector<content::DownloadItem*> DownloadVector;

  // FilterCallback is a Callback that takes a DownloadItem and returns true if
  // the item matches the filter and false otherwise.
  // query.AddFilter(base::Bind(&YourFilterFunction));
  typedef base::Callback<bool(const content::DownloadItem&)> FilterCallback;

  // All times are ISO 8601 strings.
  enum FilterType {
    FILTER_BYTES_RECEIVED,       // int
    FILTER_DANGER_ACCEPTED,      // bool
    FILTER_ENDED_AFTER,          // string
    FILTER_ENDED_BEFORE,         // string
    FILTER_END_TIME,             // string
    FILTER_EXISTS,               // bool
    FILTER_FILENAME,             // string
    FILTER_FILENAME_REGEX,       // string
    FILTER_MIME,                 // string
    FILTER_PAUSED,               // bool
    FILTER_QUERY,                // vector<base::string16>
    FILTER_STARTED_AFTER,        // string
    FILTER_STARTED_BEFORE,       // string
    FILTER_START_TIME,           // string
    FILTER_TOTAL_BYTES,          // int
    FILTER_TOTAL_BYTES_GREATER,  // int
    FILTER_TOTAL_BYTES_LESS,     // int
    FILTER_URL,                  // string
    FILTER_URL_REGEX,            // string
  };

  enum SortType {
    SORT_BYTES_RECEIVED,
    SORT_DANGER,
    SORT_DANGER_ACCEPTED,
    SORT_END_TIME,
    SORT_EXISTS,
    SORT_FILENAME,
    SORT_MIME,
    SORT_PAUSED,
    SORT_START_TIME,
    SORT_STATE,
    SORT_TOTAL_BYTES,
    SORT_URL,
  };

  enum SortDirection {
    ASCENDING,
    DESCENDING,
  };

  DownloadQuery();
  ~DownloadQuery();

  // Adds a new filter of type |type| with value |value| and returns true if
  // |type| is valid and |value| is the correct Value-type and well-formed.
  // Returns false if |type| is invalid or |value| is the incorrect Value-type
  // or malformed.  Search() will filter out all DownloadItem*s that do not
  // match all filters.  Multiple instances of the same FilterType are allowed,
  // so you can pass two regexes to AddFilter(URL_REGEX,...) in order to
  // Search() for items whose url matches both regexes. You can also pass two
  // different DownloadStates to AddFilter(), which will cause Search() to
  // filter out all items.
  bool AddFilter(const FilterCallback& filter);
  bool AddFilter(FilterType type, const base::Value& value);
  void AddFilter(content::DownloadDangerType danger);
  void AddFilter(content::DownloadItem::DownloadState state);

  // Adds a new sorter of type |type| with direction |direction|.  After
  // filtering DownloadItem*s, Search() will sort the results primarily by the
  // sorter from the first call to Sort(), secondarily by the sorter from the
  // second call to Sort(), and so on. For example, if the InputIterator passed
  // to Search() yields four DownloadItems {id:0, error:0, start_time:0}, {id:1,
  // error:0, start_time:1}, {id:2, error:1, start_time:0}, {id:3, error:1,
  // start_time:1}, and Sort is called twice, once with (SORT_ERROR, ASCENDING)
  // then with (SORT_START_TIME, DESCENDING), then Search() will return items
  // ordered 1,0,3,2.
  void AddSorter(SortType type, SortDirection direction);

  // Limit the size of search results to |limit|.
  void Limit(size_t limit) { limit_ = limit; }

  // Filters DownloadItem*s from |iter| to |last| into |results|, sorts
  // |results|, and limits the size of |results|. |results| must be non-NULL.
  template <typename InputIterator>
  void Search(InputIterator iter, const InputIterator last,
              DownloadVector* results) const {
    results->clear();
    for (; iter != last; ++iter) {
      if (Matches(**iter)) results->push_back(*iter);
    }
    FinishSearch(results);
  }

 private:
  struct Sorter;
  class DownloadComparator;
  typedef std::vector<FilterCallback> FilterCallbackVector;
  typedef std::vector<Sorter> SorterVector;

  bool FilterRegex(const std::string& regex_str,
                   const base::Callback<std::string(
                       const content::DownloadItem&)>& accessor);
  bool Matches(const content::DownloadItem& item) const;
  void FinishSearch(DownloadVector* results) const;

  FilterCallbackVector filters_;
  SorterVector sorters_;
  size_t limit_;

  DISALLOW_COPY_AND_ASSIGN(DownloadQuery);
};

#endif  // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_QUERY_H_
