// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/backoff_entry_serializer.h"

#include <algorithm>
#include <ostream>
#include <utility>

#include "base/notreached.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/tick_clock.h"
#include "base/values.h"
#include "net/base/backoff_entry.h"

namespace {
// This max defines how many times we are willing to call
// |BackoffEntry::InformOfRequest| in |DeserializeFromList|.
//
// This value is meant to large enough that the computed backoff duration can
// still be saturated. Given that the duration is an int64 and assuming 1.01 as
// a conservative lower bound for BackoffEntry::Policy::multiply_factor,
// ceil(log(2**63-1, 1.01)) = 4389.
const int kMaxFailureCount = 4389;

// This function returns true iff |duration| is finite and can be serialized and
// deserialized without becoming infinite. This function is aligned with the
// latest version.
bool BackoffDurationSafeToSerialize(const base::TimeDelta& duration) {
  return !duration.is_inf() &&
         !base::Microseconds(duration.InMicroseconds()).is_inf();
}
}  // namespace

namespace net {

base::Value::List BackoffEntrySerializer::SerializeToList(
    const BackoffEntry& entry,
    base::Time time_now) {
  base::Value::List serialized;
  serialized.Append(SerializationFormatVersion::kVersion2);

  serialized.Append(entry.failure_count());

  // Convert both |base::TimeTicks| values into |base::TimeDelta| values by
  // subtracting |kZeroTicks. This way, the top-level subtraction uses
  // |base::TimeDelta::operator-|, which has clamping semantics.
  const base::TimeTicks kZeroTicks;
  const base::TimeDelta kReleaseTime = entry.GetReleaseTime() - kZeroTicks;
  const base::TimeDelta kTimeTicksNow = entry.GetTimeTicksNow() - kZeroTicks;
  base::TimeDelta backoff_duration;
  if (!kReleaseTime.is_inf() && !kTimeTicksNow.is_inf()) {
    backoff_duration = kReleaseTime - kTimeTicksNow;
  }
  if (!BackoffDurationSafeToSerialize(backoff_duration)) {
    backoff_duration = base::TimeDelta();
  }

  base::Time absolute_release_time = backoff_duration + time_now;
  // If the computed release time is infinite, default to zero. The deserializer
  // should pick up on this.
  if (absolute_release_time.is_inf()) {
    absolute_release_time = base::Time();
  }

  // Redundantly stores both the remaining time delta and the absolute time.
  // The delta is used to work around some cases where wall clock time changes.
  serialized.Append(base::NumberToString(backoff_duration.InMicroseconds()));
  serialized.Append(
      base::NumberToString(absolute_release_time.ToInternalValue()));

  return serialized;
}

std::unique_ptr<BackoffEntry> BackoffEntrySerializer::DeserializeFromList(
    const base::Value::List& serialized,
    const BackoffEntry::Policy* policy,
    const base::TickClock* tick_clock,
    base::Time time_now) {
  if (serialized.size() != 4)
    return nullptr;

  if (!serialized[0].is_int())
    return nullptr;
  int version_number = serialized[0].GetInt();
  if (version_number != kVersion1 && version_number != kVersion2)
    return nullptr;

  if (!serialized[1].is_int())
    return nullptr;
  int failure_count = serialized[1].GetInt();
  if (failure_count < 0) {
    return nullptr;
  }
  failure_count = std::min(failure_count, kMaxFailureCount);

  base::TimeDelta original_backoff_duration;
  switch (version_number) {
    case kVersion1: {
      if (!serialized[2].is_double())
        return nullptr;
      double original_backoff_duration_double = serialized[2].GetDouble();
      original_backoff_duration =
          base::Seconds(original_backoff_duration_double);
      break;
    }
    case kVersion2: {
      if (!serialized[2].is_string())
        return nullptr;
      std::string original_backoff_duration_string = serialized[2].GetString();
      int64_t original_backoff_duration_us;
      if (!base::StringToInt64(original_backoff_duration_string,
                               &original_backoff_duration_us)) {
        return nullptr;
      }
      original_backoff_duration =
          base::Microseconds(original_backoff_duration_us);
      break;
    }
    default:
      NOTREACHED() << "Unexpected version_number: " << version_number;
  }

  if (!serialized[3].is_string())
    return nullptr;
  std::string absolute_release_time_string = serialized[3].GetString();

  int64_t absolute_release_time_us;
  if (!base::StringToInt64(absolute_release_time_string,
                           &absolute_release_time_us)) {
    return nullptr;
  }

  auto entry = std::make_unique<BackoffEntry>(policy, tick_clock);

  for (int n = 0; n < failure_count; n++)
    entry->InformOfRequest(false);

  base::Time absolute_release_time =
      base::Time::FromInternalValue(absolute_release_time_us);

  base::TimeDelta backoff_duration;
  if (absolute_release_time == base::Time()) {
    // When the serializer cannot compute a finite release time, it uses zero.
    // When we see this, fall back to the redundant original_backoff_duration.
    backoff_duration = original_backoff_duration;
  } else {
    // Before computing |backoff_duration|, throw out +/- infinity values for
    // either operand. This way, we can use base::TimeDelta's saturated math.
    if (absolute_release_time.is_inf() || time_now.is_inf())
      return nullptr;

    backoff_duration = absolute_release_time.ToDeltaSinceWindowsEpoch() -
                       time_now.ToDeltaSinceWindowsEpoch();

    // In cases where the system wall clock is rewound, use the redundant
    // original_backoff_duration to ensure the backoff duration isn't longer
    // than it was before serializing (note that it's not possible to protect
    // against the clock being wound forward).
    if (backoff_duration > original_backoff_duration)
      backoff_duration = original_backoff_duration;
  }
  if (!BackoffDurationSafeToSerialize(backoff_duration))
    return nullptr;

  const base::TimeTicks release_time =
      entry->BackoffDurationToReleaseTime(backoff_duration);
  if (release_time.is_inf())
    return nullptr;
  entry->SetCustomReleaseTime(release_time);

  return entry;
}

}  // namespace net
