// Copyright (c) 2011 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 "chrome/browser/net/url_info.h"

#include <math.h>

#include <algorithm>
#include <string>

#include "base/format_macros.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/string_util.h"

using base::Time;
using base::TimeDelta;
using base::TimeTicks;

namespace chrome_browser_net {

static bool detailed_logging_enabled = false;

// Use command line switch to enable detailed logging.
void EnablePredictorDetailedLog(bool enable) {
  detailed_logging_enabled = enable;
}

// static
int UrlInfo::sequence_counter = 1;

UrlInfo::UrlInfo()
    : state_(PENDING),
      old_prequeue_state_(state_),
      resolve_duration_(kNullDuration),
      queue_duration_(kNullDuration),
      sequence_number_(0),
      motivation_(NO_PREFETCH_MOTIVATION),
      was_linked_(false) {
}

UrlInfo::~UrlInfo() {}

bool UrlInfo::NeedsDnsUpdate() {
  switch (state_) {
    case PENDING:  // Just now created info.
      return true;

    case QUEUED:  // In queue.
    case ASSIGNED:  // It's being resolved.
    case ASSIGNED_BUT_MARKED:  // It's being resolved.
      return false;  // We're already working on it

    case NO_SUCH_NAME:  // Lookup failed.
    case FOUND:  // Lookup succeeded.
      return !IsStillCached();  // See if DNS cache expired.

    default:
      NOTREACHED();
      return false;
  }
}

const TimeDelta UrlInfo::kNullDuration(TimeDelta::FromMilliseconds(-1));

// Common low end TTL for sites is 5 minutes.  However, DNS servers give us
// the remaining time, not the original 5 minutes.  Hence it doesn't much matter
// whether we found something in the local cache, or an ISP cache, it will
// on average be 2.5 minutes before it expires.  We could try to model this with
// 180 seconds, but simpler is just to do the lookups all the time (wasting
// OS calls(?)), and let that OS cache decide what to do (with TTL in hand).
// We use a small time to help get some duplicate suppression, in case a page
// has a TON of copies of the same domain name, so that we don't thrash the OS
// to death.  Hopefully it is small enough that we're not hurting our cache hit
// rate (i.e., we could always ask the OS).
TimeDelta UrlInfo::cache_expiration_duration_(TimeDelta::FromSeconds(5));

const TimeDelta UrlInfo::kMaxNonNetworkDnsLookupDuration(
    TimeDelta::FromMilliseconds(15));

// Used by test ONLY.  The value is otherwise constant.
// static
void UrlInfo::set_cache_expiration(TimeDelta time) {
  cache_expiration_duration_ = time;
}

// static
TimeDelta UrlInfo::get_cache_expiration() {
  return cache_expiration_duration_;
}

void UrlInfo::SetQueuedState(ResolutionMotivation motivation) {
  DCHECK(PENDING == state_ || FOUND == state_ || NO_SUCH_NAME == state_);
  old_prequeue_state_ = state_;
  state_ = QUEUED;
  queue_duration_ = resolve_duration_ = kNullDuration;
  SetMotivation(motivation);
  GetDuration();  // Set time_
  DLogResultsStats("DNS Prefetch in queue");
}

void UrlInfo::SetAssignedState() {
  DCHECK(QUEUED == state_);
  state_ = ASSIGNED;
  queue_duration_ = GetDuration();
  DLogResultsStats("DNS Prefetch assigned");
  UMA_HISTOGRAM_TIMES("DNS.PrefetchQueue", queue_duration_);
}

void UrlInfo::RemoveFromQueue() {
  DCHECK(ASSIGNED == state_);
  state_ = old_prequeue_state_;
  DLogResultsStats("DNS Prefetch reset to prequeue");
  static const TimeDelta kBoundary = TimeDelta::FromSeconds(2);
  if (queue_duration_ > kBoundary) {
    UMA_HISTOGRAM_MEDIUM_TIMES("DNS.QueueRecycledDeltaOver2",
                               queue_duration_ - kBoundary);
    return;
  }
  // Make a custom linear histogram for the region from 0 to boundary.
  const size_t kBucketCount = 52;
  static base::Histogram* histogram(NULL);
  if (!histogram)
    histogram = base::LinearHistogram::FactoryTimeGet(
        "DNS.QueueRecycledUnder2", TimeDelta(), kBoundary, kBucketCount,
        base::Histogram::kUmaTargetedHistogramFlag);
  histogram->AddTime(queue_duration_);
}

void UrlInfo::SetPendingDeleteState() {
  DCHECK(ASSIGNED == state_  || ASSIGNED_BUT_MARKED == state_);
  state_ = ASSIGNED_BUT_MARKED;
}

void UrlInfo::SetFoundState() {
  DCHECK(ASSIGNED == state_);
  state_ = FOUND;
  resolve_duration_ = GetDuration();
  if (kMaxNonNetworkDnsLookupDuration <= resolve_duration_) {
    UMA_HISTOGRAM_CUSTOM_TIMES("DNS.PrefetchResolution", resolve_duration_,
        kMaxNonNetworkDnsLookupDuration, TimeDelta::FromMinutes(15), 100);
  }
  sequence_number_ = sequence_counter++;
  DLogResultsStats("DNS PrefetchFound");
}

void UrlInfo::SetNoSuchNameState() {
  DCHECK(ASSIGNED == state_);
  state_ = NO_SUCH_NAME;
  resolve_duration_ = GetDuration();
  if (kMaxNonNetworkDnsLookupDuration <= resolve_duration_) {
    DHISTOGRAM_TIMES("DNS.PrefetchNotFoundName", resolve_duration_);
  }
  sequence_number_ = sequence_counter++;
  DLogResultsStats("DNS PrefetchNotFound");
}

void UrlInfo::SetUrl(const GURL& url) {
  if (url_.is_empty())  // Not yet initialized.
    url_ = url;
  else
    DCHECK_EQ(url_, url);
}

// IsStillCached() guesses if the DNS cache still has IP data,
// or at least remembers results about "not finding host."
bool UrlInfo::IsStillCached() const {
  DCHECK(FOUND == state_ || NO_SUCH_NAME == state_);

  // Default MS OS does not cache failures. Hence we could return false almost
  // all the time for that case.  However, we'd never try again to prefetch
  // the value if we returned false that way.  Hence we'll just let the lookup
  // time out the same way as FOUND case.

  if (sequence_counter - sequence_number_ > kMaxGuaranteedDnsCacheSize)
    return false;

  TimeDelta time_since_resolution = TimeTicks::Now() - time_;

  return time_since_resolution < cache_expiration_duration_;
}

void UrlInfo::DLogResultsStats(const char* message) const {
  if (!detailed_logging_enabled)
    return;
  DVLOG(1) << "\t" << message << "\tq=" << queue_duration().InMilliseconds()
           << "ms,\tr=" << resolve_duration().InMilliseconds()
           << "ms,\tp=" << sequence_number_ << "\t" << url_.spec();
}

//------------------------------------------------------------------------------
// This last section supports HTML output, such as seen in about:dns.
//------------------------------------------------------------------------------

// Preclude any possibility of Java Script or markup in the text, by only
// allowing alphanumerics, '.', '-', ':', and whitespace.
static std::string RemoveJs(const std::string& text) {
  std::string output(text);
  size_t length = output.length();
  for (size_t i = 0; i < length; i++) {
    char next = output[i];
    if (isalnum(next) || isspace(next) || strchr(".-:/", next) != NULL)
      continue;
    output[i] = '?';
  }
  return output;
}

class MinMaxAverage {
 public:
  MinMaxAverage()
    : sum_(0), square_sum_(0), count_(0),
      minimum_(kint64max), maximum_(kint64min) {
  }

  // Return values for use in printf formatted as "%d"
  int sample(int64 value) {
    sum_ += value;
    square_sum_ += value * value;
    count_++;
    minimum_ = std::min(minimum_, value);
    maximum_ = std::max(maximum_, value);
    return static_cast<int>(value);
  }
  int minimum() const { return static_cast<int>(minimum_);    }
  int maximum() const { return static_cast<int>(maximum_);    }
  int average() const { return static_cast<int>(sum_/count_); }
  int     sum() const { return static_cast<int>(sum_);        }

  int standard_deviation() const {
    double average = static_cast<float>(sum_) / count_;
    double variance = static_cast<float>(square_sum_)/count_
                      - average * average;
    return static_cast<int>(floor(sqrt(variance) + .5));
  }

 private:
  int64 sum_;
  int64 square_sum_;
  int count_;
  int64 minimum_;
  int64 maximum_;

  // DISALLOW_COPY_AND_ASSIGN(MinMaxAverage);
};

static std::string HoursMinutesSeconds(int seconds) {
  std::string result;
  int print_seconds = seconds % 60;
  int minutes = seconds / 60;
  int print_minutes = minutes % 60;
  int print_hours = minutes/60;
  if (print_hours)
    base::StringAppendF(&result, "%.2d:",  print_hours);
  if (print_hours || print_minutes)
    base::StringAppendF(&result, "%2.2d:",  print_minutes);
  base::StringAppendF(&result, "%2.2d",  print_seconds);
  return result;
}

// static
void UrlInfo::GetHtmlTable(const UrlInfoTable& host_infos,
                           const char* description,
                           bool brief,
                           std::string* output) {
  if (0 == host_infos.size())
    return;
  output->append(description);
  base::StringAppendF(output, "%" PRIuS " %s", host_infos.size(),
                      (1 == host_infos.size()) ? "hostname" : "hostnames");

  if (brief) {
    output->append("<br><br>");
    return;
  }

  output->append("<br><table border=1>"
      "<tr><th>Host name</th>"
      "<th>How long ago<br>(HH:MM:SS)</th>"
      "<th>Motivation</th>"
      "</tr>");

  const char* row_format = "<tr align=right><td>%s</td>"  // Host name.
                           "<td>%s</td>"                  // How long ago.
                           "<td>%s</td>"                  // Motivation.
                           "</tr>";

  // Print bulk of table, and gather stats at same time.
  MinMaxAverage queue, when;
  TimeTicks current_time = TimeTicks::Now();
  for (UrlInfoTable::const_iterator it(host_infos.begin());
       it != host_infos.end(); it++) {
    queue.sample((it->queue_duration_.InMilliseconds()));
    base::StringAppendF(
        output,
        row_format,
        RemoveJs(it->url_.spec()).c_str(),
                 HoursMinutesSeconds(when.sample(
                     (current_time - it->time_).InSeconds())).c_str(),
        it->GetAsciiMotivation().c_str());
  }
  output->append("</table>");

#ifndef NDEBUG
  base::StringAppendF(
      output,
      "Prefetch Queue Durations: min=%d, avg=%d, max=%d<br><br>",
      queue.minimum(), queue.average(), queue.maximum());
#endif

  output->append("<br>");
}

void UrlInfo::SetMotivation(ResolutionMotivation motivation) {
  motivation_ = motivation;
  if (motivation < LINKED_MAX_MOTIVATED)
    was_linked_ = true;
}

std::string UrlInfo::GetAsciiMotivation() const {
  switch (motivation_) {
    case MOUSE_OVER_MOTIVATED:
      return "[mouse-over]";

    case PAGE_SCAN_MOTIVATED:
      return "[page scan]";

    case OMNIBOX_MOTIVATED:
      return "[omnibox]";

    case STARTUP_LIST_MOTIVATED:
      return "[startup list]";

    case NO_PREFETCH_MOTIVATION:
      return "n/a";

    case STATIC_REFERAL_MOTIVATED:
      return RemoveJs(referring_url_.spec()) + "*";

    case LEARNED_REFERAL_MOTIVATED:
      return RemoveJs(referring_url_.spec());

    default:
      return "";
  }
}

}  // namespace chrome_browser_net
