// Copyright 2017 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 "components/previews/core/previews_logger.h"

#include "base/command_line.h"
#include "base/strings/stringprintf.h"
#include "components/previews/core/previews_logger_observer.h"
#include "components/previews/core/previews_switches.h"

namespace previews {

std::string GetDescriptionForInfoBarDescription(previews::PreviewsType type) {
  return base::StringPrintf("%s InfoBar shown",
                            previews::GetStringNameForType(type).c_str());
}

namespace {

static const char kPreviewDecisionMadeEventType[] = "Decision";
static const char kPreviewNavigationEventType[] = "Navigation";
const size_t kMaximumNavigationLogs = 10;
const size_t kMaximumDecisionLogs = 25;

std::string GetDescriptionForPreviewsNavigation(PreviewsType type,
                                                bool opt_out) {
  return base::StringPrintf("%s preview - user opt-out: %s",
                            GetStringNameForType(type).c_str(),
                            opt_out ? "True" : "False");
}

std::string GetReasonDescription(PreviewsEligibilityReason reason,
                                 bool want_inverse_description) {
  switch (reason) {
    case PreviewsEligibilityReason::ALLOWED:
      DCHECK(!want_inverse_description);
      return "Allowed";
    case PreviewsEligibilityReason::BLACKLIST_UNAVAILABLE:
      return want_inverse_description ? "Blacklist not null"
                                      : "Blacklist failed to be created";
    case PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED:
      return want_inverse_description ? "Blacklist loaded from disk"
                                      : "Blacklist not loaded from disk yet";
    case PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT:
      return want_inverse_description ? "User did not opt out recently"
                                      : "User recently opted out";
    case PreviewsEligibilityReason::USER_BLACKLISTED:
      return want_inverse_description ? "Not all previews are blacklisted"
                                      : "All previews are blacklisted";
    case PreviewsEligibilityReason::HOST_BLACKLISTED:
      return want_inverse_description
                 ? "Host is not blacklisted on all previews"
                 : "All previews on this host are blacklisted";
    case PreviewsEligibilityReason::NETWORK_QUALITY_UNAVAILABLE:
      return want_inverse_description ? "Network quality available"
                                      : "Network quality unavailable";
    case PreviewsEligibilityReason::NETWORK_NOT_SLOW:
      return want_inverse_description ? "Network is slow" : "Network not slow";
    case PreviewsEligibilityReason::RELOAD_DISALLOWED:
      return want_inverse_description
                 ? "Page reloads allowed"
                 : "Page reloads do not show previews for this preview type";
    case PreviewsEligibilityReason::HOST_BLACKLISTED_BY_SERVER:
      return want_inverse_description ? "Host not blacklisted by server rules"
                                      : "Host blacklisted by server rules";
    case PreviewsEligibilityReason::HOST_NOT_WHITELISTED_BY_SERVER:
      return want_inverse_description ? "Host whitelisted by server rules"
                                      : "Host not whitelisted by server rules";
    case PreviewsEligibilityReason::ALLOWED_WITHOUT_OPTIMIZATION_HINTS:
      return want_inverse_description
                 ? "Not allowed (without server rule check)"
                 : "Allowed (but without server rule check)";
    case PreviewsEligibilityReason::COMMITTED:
      return want_inverse_description ? "Not Committed" : "Committed";
    case PreviewsEligibilityReason::CACHE_CONTROL_NO_TRANSFORM:
      return want_inverse_description
                 ? "Cache-control no-transform not received"
                 : "Cache-control no-transform received";
    case PreviewsEligibilityReason::LAST:
      break;
  }
  NOTREACHED();
  return "";
}

std::string GetDescriptionForPreviewsDecision(
    PreviewsEligibilityReason reason,
    PreviewsType type,
    bool want_inverse_description = false) {
  return base::StringPrintf(
      "%s preview - %s", GetStringNameForType(type).c_str(),
      GetReasonDescription(reason, want_inverse_description).c_str());
}

}  // namespace

PreviewsLogger::MessageLog::MessageLog(const std::string& event_type,
                                       const std::string& event_description,
                                       const GURL& url,
                                       base::Time time,
                                       uint64_t page_id)
    : event_type(event_type),
      event_description(event_description),
      url(url),
      time(time),
      page_id(page_id) {}

PreviewsLogger::MessageLog::MessageLog(const MessageLog& other)
    : event_type(other.event_type),
      event_description(other.event_description),
      url(other.url),
      time(other.time),
      page_id(other.page_id) {}

PreviewsLogger::PreviewsLogger()
    : blacklist_ignored_(base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kIgnorePreviewsBlacklist)) {}

PreviewsLogger::~PreviewsLogger() {}

void PreviewsLogger::AddAndNotifyObserver(PreviewsLoggerObserver* observer) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  observer_list_.AddObserver(observer);
  // Notify the status of blacklist decisions ingored.
  observer->OnIgnoreBlacklistDecisionStatusChanged(blacklist_ignored_);

  // Merge navigation logs and decision logs in chronological order, and push
  // them to |observer|.
  auto navigation_ptr = navigations_logs_.begin();
  auto decision_ptr = decisions_logs_.begin();
  while (navigation_ptr != navigations_logs_.end() ||
         decision_ptr != decisions_logs_.end()) {
    if (navigation_ptr == navigations_logs_.end()) {
      observer->OnNewMessageLogAdded(*decision_ptr);
      ++decision_ptr;
      continue;
    }
    if (decision_ptr == decisions_logs_.end()) {
      observer->OnNewMessageLogAdded(*navigation_ptr);
      ++navigation_ptr;
      continue;
    }
    if (navigation_ptr->time < decision_ptr->time) {
      observer->OnNewMessageLogAdded(*navigation_ptr);
      ++navigation_ptr;
    } else {
      observer->OnNewMessageLogAdded(*decision_ptr);
      ++decision_ptr;
    }
  }

  // Push the current state of blacklist (user blacklisted state and all
  // blacklisted hosts).
  observer->OnUserBlacklistedStatusChange(user_blacklisted_status_);
  for (auto entry : blacklisted_hosts_) {
    observer->OnNewBlacklistedHost(entry.first, entry.second);
  }
}

void PreviewsLogger::RemoveObserver(PreviewsLoggerObserver* observer) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  observer_list_.RemoveObserver(observer);
  if (observer_list_.begin() == observer_list_.end()) {
    // |observer_list_| is empty.
    observer->OnLastObserverRemove();
  }
}

void PreviewsLogger::LogMessage(const std::string& event_type,
                                const std::string& event_description,
                                const GURL& url,
                                base::Time time,
                                uint64_t page_id) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  // Notify observers about the new MessageLog.
  for (auto& observer : observer_list_) {
    observer.OnNewMessageLogAdded(
        MessageLog(event_type, event_description, url, time, page_id));
  }
}

void PreviewsLogger::LogPreviewNavigation(const GURL& url,
                                          PreviewsType type,
                                          bool opt_out,
                                          base::Time time,
                                          uint64_t page_id) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK_GE(kMaximumNavigationLogs, navigations_logs_.size());

  std::string description = GetDescriptionForPreviewsNavigation(type, opt_out);
  LogMessage(kPreviewNavigationEventType, description, url, time, page_id);

  // Pop out the oldest message when the list is full.
  if (navigations_logs_.size() >= kMaximumNavigationLogs) {
    navigations_logs_.pop_front();
  }

  navigations_logs_.emplace_back(kPreviewNavigationEventType, description, url,
                                 time, page_id);
}

void PreviewsLogger::LogPreviewDecisionMade(
    PreviewsEligibilityReason reason,
    const GURL& url,
    base::Time time,
    PreviewsType type,
    std::vector<PreviewsEligibilityReason>&& passed_reasons,
    uint64_t page_id) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK_GE(kMaximumDecisionLogs, decisions_logs_.size());

  // Logs all passed decisions messages.
  for (auto decision : passed_reasons) {
    std::string decision_description = GetDescriptionForPreviewsDecision(
        decision, type, true /* want_inverse_description */);
    LogMessage(kPreviewDecisionMadeEventType, decision_description, url, time,
               page_id);
    decisions_logs_.emplace_back(kPreviewDecisionMadeEventType,
                                 decision_description, url, time, page_id);
  }

  std::string description = GetDescriptionForPreviewsDecision(reason, type);
  LogMessage(kPreviewDecisionMadeEventType, description, url, time, page_id);

  // Pop out the older messages when the list is full.
  while (decisions_logs_.size() >= kMaximumDecisionLogs) {
    decisions_logs_.pop_front();
  }

  decisions_logs_.emplace_back(kPreviewDecisionMadeEventType, description, url,
                               time, page_id);
}

void PreviewsLogger::OnNewBlacklistedHost(const std::string& host,
                                          base::Time time) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  blacklisted_hosts_[host] = time;
  for (auto& observer : observer_list_) {
    observer.OnNewBlacklistedHost(host, time);
  }
}

void PreviewsLogger::OnUserBlacklistedStatusChange(bool blacklisted) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  user_blacklisted_status_ = blacklisted;
  for (auto& observer : observer_list_) {
    observer.OnUserBlacklistedStatusChange(blacklisted);
  }
}

void PreviewsLogger::OnBlacklistCleared(base::Time time) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  blacklisted_hosts_.clear();
  navigations_logs_.clear();
  decisions_logs_.clear();
  for (auto& observer : observer_list_) {
    observer.OnBlacklistCleared(time);
  }
}

void PreviewsLogger::OnIgnoreBlacklistDecisionStatusChanged(bool ignored) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  blacklist_ignored_ = ignored;
  for (auto& observer : observer_list_) {
    observer.OnIgnoreBlacklistDecisionStatusChanged(ignored);
  }
}

}  // namespace previews
