// Copyright 2013 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.

#include "ui/app_list/search_controller.h"

#include <algorithm>
#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/app_list/app_list_constants.h"
#include "ui/app_list/search/history.h"
#include "ui/app_list/search_box_model.h"
#include "ui/app_list/search_provider.h"
#include "ui/app_list/search_result.h"

namespace {

// Maximum time (in milliseconds) to wait to the search providers to finish.
const int kStopTimeMS = 1500;
}

namespace app_list {

SearchController::SearchController(SearchBoxModel* search_box,
                                   AppListModel::SearchResults* results,
                                   History* history)
    : search_box_(search_box), mixer_(new Mixer(results)), history_(history) {}

SearchController::~SearchController() {
}

void SearchController::Start(bool is_voice_query) {
  Stop();

  base::string16 query;
  base::TrimWhitespace(search_box_->text(), base::TRIM_ALL, &query);

  dispatching_query_ = true;
  for (Providers::iterator it = providers_.begin();
       it != providers_.end();
       ++it) {
    (*it)->Start(is_voice_query, query);
  }
  dispatching_query_ = false;
  query_for_recommendation_ = query.empty() ? true : false;

  is_voice_query_ = is_voice_query;

  OnResultsChanged();

  stop_timer_.Start(FROM_HERE,
                    base::TimeDelta::FromMilliseconds(kStopTimeMS),
                    base::Bind(&SearchController::Stop,
                               base::Unretained(this)));
}

void SearchController::Stop() {
  stop_timer_.Stop();

  for (Providers::iterator it = providers_.begin();
       it != providers_.end();
       ++it) {
    (*it)->Stop();
  }
}

void SearchController::OpenResult(SearchResult* result, int event_flags) {
  // This can happen in certain circumstances due to races. See
  // https://crbug.com/534772
  if (!result)
    return;

  // Count AppList.Search here because it is composed of search + action.
  base::RecordAction(base::UserMetricsAction("AppList_Search"));

  UMA_HISTOGRAM_ENUMERATION(kSearchResultOpenDisplayTypeHistogram,
                            result->display_type(),
                            SearchResult::DISPLAY_TYPE_LAST);

  if (result->display_type() != SearchResult::DISPLAY_RECOMMENDATION) {
    UMA_HISTOGRAM_COUNTS_100(kSearchQueryLength, search_box_->text().size());

    if (result->distance_from_origin() >= 0) {
      UMA_HISTOGRAM_COUNTS_100(kSearchResultDistanceFromOrigin,
                               result->distance_from_origin());
    }
  }

  result->Open(event_flags);

  if (history_ && history_->IsReady()) {
    history_->AddLaunchEvent(base::UTF16ToUTF8(search_box_->text()),
                             result->id());
  }
}

void SearchController::InvokeResultAction(SearchResult* result,
                                          int action_index,
                                          int event_flags) {
  // TODO(xiyuan): Hook up with user learning.
  result->InvokeAction(action_index, event_flags);
}

size_t SearchController::AddGroup(size_t max_results, double multiplier) {
  return mixer_->AddGroup(max_results, multiplier);
}

void SearchController::AddProvider(size_t group_id,
                                   std::unique_ptr<SearchProvider> provider) {
  provider->set_result_changed_callback(
      base::Bind(&SearchController::OnResultsChanged, base::Unretained(this)));
  mixer_->AddProviderToGroup(group_id, provider.get());
  providers_.push_back(std::move(provider));
}

void SearchController::OnResultsChanged() {
  if (dispatching_query_)
    return;

  KnownResults known_results;
  if (history_ && history_->IsReady()) {
    history_->GetKnownResults(base::UTF16ToUTF8(search_box_->text()))
        ->swap(known_results);
  }

  size_t num_max_results =
      query_for_recommendation_ ? kNumStartPageTiles : kMaxSearchResults;
  mixer_->MixAndPublish(is_voice_query_, known_results, num_max_results);
}

}  // namespace app_list
