// Copyright (C) 2013 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gwtexpui.server;

import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.SECONDS;

import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/** Utilities to manage HTTP caching directives in responses. */
public class CacheHeaders {
  private static final long MAX_CACHE_DURATION = DAYS.toSeconds(365);

  /**
   * Do not cache the response, anywhere.
   *
   * @param res response being returned.
   */
  public static void setNotCacheable(HttpServletResponse res) {
    String cc = "no-cache, no-store, max-age=0, must-revalidate";
    res.setHeader("Cache-Control", cc);
    res.setHeader("Pragma", "no-cache");
    res.setHeader("Expires", "Fri, 01 Jan 1990 00:00:00 GMT");
    res.setDateHeader("Date", System.currentTimeMillis());
  }

  /**
   * Permit caching the response for up to the age specified.
   * <p>
   * If the request is on a secure connection (e.g. SSL) private caching is
   * used. This allows the user-agent to cache the response, but requests
   * intermediate proxies to not cache. This may offer better protection for
   * Set-Cookie headers.
   * <p>
   * If the request is on plaintext (insecure), public caching is used. This may
   * allow an intermediate proxy to cache the response, including any Set-Cookie
   * header that may have also been included.
   *
   * @param req current request.
   * @param res response being returned.
   * @param age how long the response can be cached.
   * @param unit time unit for age, usually {@link TimeUnit#SECONDS}.
   */
  public static void setCacheable(
      HttpServletRequest req, HttpServletResponse res,
      long age, TimeUnit unit) {
    if (req.isSecure()) {
      setCacheablePrivate(res, age, unit);
    } else {
      setCacheablePublic(res, age, unit);
    }
  }

  /**
   * Allow the response to be cached by proxies and user-agents.
   * <p>
   * If the response includes a Set-Cookie header the cookie may be cached by a
   * proxy and returned to multiple browsers behind the same proxy. This is
   * insecure for authenticated connections.
   *
   * @param res response being returned.
   * @param age how long the response can be cached.
   * @param unit time unit for age, usually {@link TimeUnit#SECONDS}.
   */
  public static void setCacheablePublic(HttpServletResponse res,
      long age, TimeUnit unit) {
    long now = System.currentTimeMillis();
    long sec = maxAgeSeconds(age, unit);

    res.setDateHeader("Expires", now + SECONDS.toMillis(sec));
    res.setDateHeader("Date", now);
    cache(res, "public", age, unit);
  }

  /**
   * Allow the response to be cached only by the user-agent.
   *
   * @param res response being returned.
   * @param age how long the response can be cached.
   * @param unit time unit for age, usually {@link TimeUnit#SECONDS}.
   */
  public static void setCacheablePrivate(HttpServletResponse res,
      long age, TimeUnit unit) {
    long now = System.currentTimeMillis();
    res.setDateHeader("Expires", now);
    res.setDateHeader("Date", now);
    cache(res, "private", age, unit);
  }

  private static void cache(HttpServletResponse res,
      String type, long age, TimeUnit unit) {
    res.setHeader("Cache-Control", String.format(
        "%s, max-age=%d",
        type, maxAgeSeconds(age, unit)));
  }

  private static long maxAgeSeconds(long age, TimeUnit unit) {
    return Math.min(unit.toSeconds(age), MAX_CACHE_DURATION);
  }

  private CacheHeaders() {
  }
}
