// 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 "media/blink/cache_util.h"

#include <stddef.h>

#include <string>

#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "net/http/http_util.h"
#include "net/http/http_version.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url_response.h"

using base::Time;
using base::TimeDelta;
using net::HttpVersion;
using blink::WebURLResponse;

namespace media {

enum { kHttpOK = 200, kHttpPartialContent = 206 };

uint32_t GetReasonsForUncacheability(const WebURLResponse& response) {
  uint32_t reasons = 0;
  const int code = response.HttpStatusCode();
  const int version = response.HttpVersion();
  const HttpVersion http_version =
      version == WebURLResponse::kHTTPVersion_2_0
          ? HttpVersion(2, 0)
          : version == WebURLResponse::kHTTPVersion_1_1
                ? HttpVersion(1, 1)
                : version == WebURLResponse::kHTTPVersion_1_0
                      ? HttpVersion(1, 0)
                      : version == WebURLResponse::kHTTPVersion_0_9
                            ? HttpVersion(0, 9)
                            : HttpVersion();
  if (code != kHttpOK && code != kHttpPartialContent)
    reasons |= kNoData;
  if (http_version < HttpVersion(1, 1) && code == kHttpPartialContent)
    reasons |= kPre11PartialResponse;
  if (code == kHttpPartialContent &&
      !net::HttpUtil::HasStrongValidators(
          http_version, response.HttpHeaderField("etag").Utf8(),
          response.HttpHeaderField("Last-Modified").Utf8(),
          response.HttpHeaderField("Date").Utf8())) {
    reasons |= kNoStrongValidatorOnPartialResponse;
  }

  std::string cache_control_header =
      base::ToLowerASCII(response.HttpHeaderField("cache-control").Utf8());
  if (cache_control_header.find("no-cache") != std::string::npos)
    reasons |= kNoCache;
  if (cache_control_header.find("no-store") != std::string::npos)
    reasons |= kNoStore;
  if (cache_control_header.find("must-revalidate") != std::string::npos)
    reasons |= kHasMustRevalidate;

  const TimeDelta kMinimumAgeForUsefulness =
      TimeDelta::FromSeconds(3600);  // Arbitrary value.

  const char kMaxAgePrefix[] = "max-age=";
  const size_t kMaxAgePrefixLen = base::size(kMaxAgePrefix) - 1;
  if (cache_control_header.substr(0, kMaxAgePrefixLen) == kMaxAgePrefix) {
    int64_t max_age_seconds;
    base::StringToInt64(
        base::StringPiece(cache_control_header.begin() + kMaxAgePrefixLen,
                          cache_control_header.end()),
        &max_age_seconds);
    if (TimeDelta::FromSeconds(max_age_seconds) < kMinimumAgeForUsefulness)
      reasons |= kShortMaxAge;
  }

  Time date;
  Time expires;
  if (Time::FromString(response.HttpHeaderField("Date").Utf8().data(), &date) &&
      Time::FromString(response.HttpHeaderField("Expires").Utf8().data(),
                       &expires) &&
      date > Time() && expires > Time() &&
      (expires - date) < kMinimumAgeForUsefulness) {
    reasons |= kExpiresTooSoon;
  }

  return reasons;
}

base::TimeDelta GetCacheValidUntil(const WebURLResponse& response) {
  std::string cache_control_header =
      base::ToLowerASCII(response.HttpHeaderField("cache-control").Utf8());
  if (cache_control_header.find("no-cache") != std::string::npos)
    return base::TimeDelta();
  if (cache_control_header.find("must-revalidate") != std::string::npos)
    return base::TimeDelta();

  // Max cache timeout ~= 1 month.
  base::TimeDelta ret = base::TimeDelta::FromDays(30);

  const char kMaxAgePrefix[] = "max-age=";
  const size_t kMaxAgePrefixLen = base::size(kMaxAgePrefix) - 1;
  if (cache_control_header.substr(0, kMaxAgePrefixLen) == kMaxAgePrefix) {
    int64_t max_age_seconds;
    base::StringToInt64(
        base::StringPiece(cache_control_header.begin() + kMaxAgePrefixLen,
                          cache_control_header.end()),
        &max_age_seconds);

    ret = std::min(ret, TimeDelta::FromSeconds(max_age_seconds));
  } else {
    // Note that |date| may be smaller than |expires|, which means we'll
    // return a timetick some time in the past.
    Time date;
    Time expires;
    if (Time::FromString(response.HttpHeaderField("Date").Utf8().data(),
                         &date) &&
        Time::FromString(response.HttpHeaderField("Expires").Utf8().data(),
                         &expires) &&
        date > Time() && expires > Time()) {
      ret = std::min(ret, expires - date);
    }
  }

  return ret;
}

}  // namespace media
