// 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 COMPONENTS_OMNIBOX_BROWSER_SHORTCUTS_BACKEND_H_
#define COMPONENTS_OMNIBOX_BROWSER_SHORTCUTS_BACKEND_H_

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

#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "base/scoped_observer.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string16.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "components/history/core/browser/history_service_observer.h"
#include "components/keyed_service/core/refcounted_keyed_service.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/shortcuts_database.h"
#include "components/search_engines/search_terms_data.h"
#include "url/gurl.h"

class ShortcutsBackend;
class TemplateURLService;
struct TestShortcutData;

void PopulateShortcutsBackendWithTestData(
    scoped_refptr<ShortcutsBackend> backend,
    TestShortcutData* db,
    size_t db_size);

namespace history {
class HistoryService;
class ShortcutsDatabase;
};  // namespace history

// This class manages the shortcut provider backend - access to database on the
// db thread, etc.
class ShortcutsBackend : public RefcountedKeyedService,
                         public history::HistoryServiceObserver {
 public:
  typedef std::multimap<base::string16, const ShortcutsDatabase::Shortcut>
      ShortcutMap;

  // For unit testing, set |suppress_db| to true to prevent creation
  // of the database, in which case all operations are performed in memory only.
  ShortcutsBackend(TemplateURLService* template_url_service,
                   std::unique_ptr<SearchTermsData> search_terms_data,
                   history::HistoryService* history_service,
                   scoped_refptr<base::SequencedTaskRunner> db_runner,
                   base::FilePath database_path,
                   bool suppress_db);

  // The interface is guaranteed to be called on the thread AddObserver()
  // was called.
  class ShortcutsBackendObserver {
   public:
    // Called after the database is loaded and Init() completed.
    virtual void OnShortcutsLoaded() = 0;
    // Called when shortcuts changed (added/updated/removed) in the database.
    virtual void OnShortcutsChanged() {}

   protected:
    virtual ~ShortcutsBackendObserver() {}
  };

  // Asynchronously initializes the ShortcutsBackend, it is safe to call
  // multiple times - only the first call will be processed.
  bool Init();

  // All of the public functions *must* be called on UI thread only!

  bool initialized() const { return current_state_ == INITIALIZED; }
  const ShortcutMap& shortcuts_map() const { return shortcuts_map_; }

  // Deletes the Shortcuts with the url.
  bool DeleteShortcutsWithURL(const GURL& shortcut_url);

  // Deletes the Shortcuts that begin with the url.
  bool DeleteShortcutsBeginningWithURL(const GURL& shortcut_url);

  void AddObserver(ShortcutsBackendObserver* obs);
  void RemoveObserver(ShortcutsBackendObserver* obs);

  // Looks for an existing shortcut to match.destination_url that starts with
  // |text|.  Updates that shortcut if found, otherwise adds a new shortcut.
  void AddOrUpdateShortcut(const base::string16& text,
                           const AutocompleteMatch& match);

 private:
  friend class base::RefCountedThreadSafe<ShortcutsBackend>;
  friend class ShortcutsBackendTest;
  friend void PopulateShortcutsBackendWithTestData(
      scoped_refptr<ShortcutsBackend> backend,
      TestShortcutData* db,
      size_t db_size);
  FRIEND_TEST_ALL_PREFIXES(ShortcutsBackendTest, EntitySuggestionTest);

  enum CurrentState {
    NOT_INITIALIZED,  // Backend created but not initialized.
    INITIALIZING,     // Init() called, but not completed yet.
    INITIALIZED,      // Initialization completed, all accessors can be safely
                      // called.
  };

  typedef std::map<std::string, ShortcutMap::iterator> GuidMap;

  ~ShortcutsBackend() override;

  static ShortcutsDatabase::Shortcut::MatchCore MatchToMatchCore(
      const AutocompleteMatch& match,
      TemplateURLService* template_url_service,
      SearchTermsData* search_terms_data);

  // RefcountedKeyedService:
  void ShutdownOnUIThread() override;

  // history::HistoryServiceObserver:
  void OnURLsDeleted(history::HistoryService* history_service,
                     bool all_history,
                     bool expired,
                     const history::URLRows& deleted_rows,
                     const std::set<GURL>& favicon_urls) override;

  // Internal initialization of the back-end. Posted by Init() to the DB thread.
  // On completion posts InitCompleted() back to UI thread.
  void InitInternal();

  // Finishes initialization on UI thread, notifies all observers.
  void InitCompleted();

  // Adds the Shortcut to the database.
  bool AddShortcut(const ShortcutsDatabase::Shortcut& shortcut);

  // Updates timing and selection count for the Shortcut.
  bool UpdateShortcut(const ShortcutsDatabase::Shortcut& shortcut);

  // Deletes the Shortcuts with these IDs.
  bool DeleteShortcutsWithIDs(
      const ShortcutsDatabase::ShortcutIDs& shortcut_ids);

  // Deletes all shortcuts whose URLs begin with |url|.  If |exact_match| is
  // true, only shortcuts from exactly |url| are deleted.
  bool DeleteShortcutsWithURL(const GURL& url, bool exact_match);

  // Deletes all of the shortcuts.
  bool DeleteAllShortcuts();

  TemplateURLService* template_url_service_;
  std::unique_ptr<SearchTermsData> search_terms_data_;

  CurrentState current_state_;
  base::ObserverList<ShortcutsBackendObserver> observer_list_;
  scoped_refptr<ShortcutsDatabase> db_;

  // The |temp_shortcuts_map_| and |temp_guid_map_| used for temporary storage
  // between InitInternal() and InitComplete() to avoid doing a potentially huge
  // copy.
  std::unique_ptr<ShortcutMap> temp_shortcuts_map_;
  std::unique_ptr<GuidMap> temp_guid_map_;

  ShortcutMap shortcuts_map_;
  // This is a helper map for quick access to a shortcut by guid.
  GuidMap guid_map_;

  ScopedObserver<history::HistoryService, history::HistoryServiceObserver>
      history_service_observer_;

  scoped_refptr<base::SequencedTaskRunner> main_runner_;
  scoped_refptr<base::SequencedTaskRunner> db_runner_;

  // For some unit-test only.
  bool no_db_access_;

  DISALLOW_COPY_AND_ASSIGN(ShortcutsBackend);
};

#endif  // COMPONENTS_OMNIBOX_BROWSER_SHORTCUTS_BACKEND_H_
