// 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;
    case PreviewsEligibilityReason::NETWORK_NOT_SLOW_FOR_SESSION:
      return want_inverse_description
                 ? "Network is slow enough for the session"
                 : "Network not slow enough for the session";
    case PreviewsEligibilityReason::DEVICE_OFFLINE:
      return want_inverse_description ? "Device is online"
                                      : "Device is offline";
  }
  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
