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

#include <algorithm>
#include <string>

#include "base/basictypes.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/time.h"
#include "net/http/http_util.h"
#include "net/http/http_version.h"
#include "starboard/types.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURLResponse.h"

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

namespace cobalt {
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::HTTPVersion_2_0
          ? HttpVersion(2, 0)
          : version == WebURLResponse::HTTPVersion_1_1
                ? HttpVersion(1, 1)
                : version == WebURLResponse::HTTPVersion_1_0
                      ? HttpVersion(1, 0)
                      : version == WebURLResponse::HTTPVersion_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 = arraysize(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 = arraysize(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
}  // namespace cobalt
