// Copyright (C) 2015 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.gerrit.httpd.raw;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.net.HttpHeaders.CONTENT_ENCODING;
import static com.google.common.net.HttpHeaders.ETAG;
import static com.google.common.net.HttpHeaders.IF_MODIFIED_SINCE;
import static com.google.common.net.HttpHeaders.IF_NONE_MATCH;
import static com.google.common.net.HttpHeaders.LAST_MODIFIED;
import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import static javax.servlet.http.HttpServletResponse.SC_NOT_MODIFIED;

import com.google.common.base.CharMatcher;
import com.google.common.cache.Cache;
import com.google.common.collect.ImmutableMap;
import com.google.common.hash.Hashing;
import com.google.gerrit.common.FileUtil;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.httpd.HtmlDomUtil;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.gwtjsonrpc.server.RPCServletUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.attribute.FileTime;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.zip.GZIPOutputStream;

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

/**
 * Base class for serving static resources.
 * <p>
 * Supports caching, ETags, basic content type detection, and limited gzip
 * compression.
 */
public abstract class ResourceServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;

  private static final Logger log =
      LoggerFactory.getLogger(ResourceServlet.class);

  private static final int CACHE_FILE_SIZE_LIMIT_BYTES = 100 << 10;

  private static final String JS = "application/x-javascript";
  private static final ImmutableMap<String, String> MIME_TYPES =
      ImmutableMap.<String, String> builder()
        .put("css", "text/css")
        .put("gif", "image/gif")
        .put("htm", "text/html")
        .put("html", "text/html")
        .put("jpeg", "image/jpeg")
        .put("jpg", "image/jpeg")
        .put("js", JS)
        .put("pdf", "application/pdf")
        .put("png", "image/png")
        .put("rtf", "text/rtf")
        .put("svg", "image/svg+xml")
        .put("text", "text/plain")
        .put("tif", "image/tiff")
        .put("tiff", "image/tiff")
        .put("txt", "text/plain")
        .build();

  protected static String contentType(String name) {
    int dot = name.lastIndexOf('.');
    String ext = 0 < dot ? name.substring(dot + 1) : "";
    String type = MIME_TYPES.get(ext);
    return type != null ? type : "application/octet-stream";
  }

  private final Cache<Path, Resource> cache;
  private final boolean refresh;

  protected ResourceServlet(Cache<Path, Resource> cache, boolean refresh) {
    this.cache = checkNotNull(cache, "cache");
    this.refresh = refresh;
  }

  /**
   * Get the resource path on the filesystem that should be served for this
   * request.
   *
   * @param pathInfo result of {@link HttpServletRequest#getPathInfo()}.
   * @return path where static content can be found.
   */
  protected abstract Path getResourcePath(String pathInfo);

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse rsp)
      throws IOException {
    String name = CharMatcher.is('/').trimFrom(req.getPathInfo());
    if (isUnreasonableName(name)) {
      notFound(rsp);
      return;
    }
    Path p = getResourcePath(name);
    if (p == null) {
      notFound(rsp);
      return;
    }

    Resource r = cache.getIfPresent(p);
    if (r == null && maybeStream(p, req, rsp)) {
      return;
    }

    if (r == null) {
      Callable<Resource> loader = newLoader(p);
      try {
        r = cache.get(p, loader);
        if (refresh && r.isStale(p)) {
          cache.invalidate(p);
          r = cache.get(p, loader);
        }
      } catch (ExecutionException e) {
        log.warn("Cannot load static resource " + req.getPathInfo(), e);
        CacheHeaders.setNotCacheable(rsp);
        rsp.setStatus(SC_INTERNAL_SERVER_ERROR);
        return;
      }
    }

    if (r == Resource.NOT_FOUND) {
      notFound(rsp);
      return;
    }

    String e = req.getParameter("e");
    if (e != null && !r.etag.equals(e)) {
      CacheHeaders.setNotCacheable(rsp);
      rsp.setStatus(SC_NOT_FOUND);
      return;
    } else if (r.etag.equals(req.getHeader(IF_NONE_MATCH))) {
      rsp.setStatus(SC_NOT_MODIFIED);
      return;
    }

    byte[] tosend = r.raw;
    if (!r.contentType.equals(JS) && RPCServletUtils.acceptsGzipEncoding(req)) {
      byte[] gz = HtmlDomUtil.compress(tosend);
      if ((gz.length + 24) < tosend.length) {
        rsp.setHeader(CONTENT_ENCODING, "gzip");
        tosend = gz;
      }
    }
    if (!CacheHeaders.hasCacheHeader(rsp)) {
      if (e != null && r.etag.equals(e)) {
        CacheHeaders.setCacheable(req, rsp, 360, DAYS, false);
      } else {
        CacheHeaders.setCacheable(req, rsp, 15, MINUTES, refresh);
      }
    }
    rsp.setHeader(ETAG, r.etag);
    rsp.setContentType(r.contentType);
    rsp.setContentLength(tosend.length);
    try (OutputStream out = rsp.getOutputStream()) {
      out.write(tosend);
    }
  }

  @Nullable
  Resource getResource(String name) {
    try {
      Path p = getResourcePath(name);
      return cache.get(p, newLoader(p));
    } catch (ExecutionException e) {
      log.warn(String.format("Cannot load static resource %s", name), e);
      return null;
    }
  }

  private static void notFound(HttpServletResponse rsp) {
    rsp.setStatus(SC_NOT_FOUND);
    CacheHeaders.setNotCacheable(rsp);
  }

  /**
   * Maybe stream a path to the response, depending on the properties of the
   * file and cache headers in the request.
   *
   * @param p path to stream
   * @param req HTTP request.
   * @param rsp HTTP response.
   * @return true if the response was written (either the file contents or an
   *     error); false if the path is too small to stream and should be cached.
   */
  private boolean maybeStream(Path p, HttpServletRequest req,
      HttpServletResponse rsp) throws IOException {
    try {
      if (Files.size(p) < CACHE_FILE_SIZE_LIMIT_BYTES) {
        return false;
      }
    } catch (NoSuchFileException e) {
      cache.put(p, Resource.NOT_FOUND);
      notFound(rsp);
      return true;
    }

    long lastModified = FileUtil.lastModified(p);
    if (req.getDateHeader(IF_MODIFIED_SINCE) >= lastModified) {
      rsp.setStatus(SC_NOT_MODIFIED);
      return true;
    }

    if (lastModified > 0) {
      rsp.setDateHeader(LAST_MODIFIED, lastModified);
    }
    if (!CacheHeaders.hasCacheHeader(rsp)) {
      CacheHeaders.setCacheable(req, rsp, 15, MINUTES, refresh);
    }
    rsp.setContentType(contentType(p.toString()));

    OutputStream out = rsp.getOutputStream();
    GZIPOutputStream gz = null;
    if (RPCServletUtils.acceptsGzipEncoding(req)) {
      rsp.setHeader(CONTENT_ENCODING, "gzip");
      gz = new GZIPOutputStream(out);
      out = gz;
    }
    Files.copy(p, out);
    if (gz != null) {
      gz.finish();
    }
    return true;
  }


  private static boolean isUnreasonableName(String name) {
    return name.length() < 1
      || name.contains("\\") // no windows/dos style paths
      || name.startsWith("../") // no "../etc/passwd"
      || name.contains("/../") // no "foo/../etc/passwd"
      || name.contains("/./") // "foo/./foo" is insane to ask
      || name.contains("//"); // windows UNC path can be "//..."
  }

  private Callable<Resource> newLoader(final Path p) {
    return new Callable<Resource>() {
      @Override
      public Resource call() throws IOException {
        try {
          return new Resource(
              Files.getLastModifiedTime(p),
              contentType(p.toString()),
              Files.readAllBytes(p));
        } catch (NoSuchFileException e) {
          return Resource.NOT_FOUND;
        }
      }
    };
  }

  static class Resource {
    static final Resource NOT_FOUND =
        new Resource(FileTime.fromMillis(0), "", new byte[] {});

    final FileTime lastModified;
    final String contentType;
    final String etag;
    final byte[] raw;

    Resource(FileTime lastModified, String contentType, byte[] raw) {
      this.lastModified = checkNotNull(lastModified, "lastModified");
      this.contentType = checkNotNull(contentType, "contentType");
      this.raw = checkNotNull(raw, "raw");
      this.etag = Hashing.md5().hashBytes(raw).toString();
    }

    boolean isStale(Path p) {
      try {
        return !lastModified.equals(Files.getLastModifiedTime(p));
      } catch (IOException e) {
        return true;
      }
    }
  }

  static class Weigher
      implements com.google.common.cache.Weigher<Path, Resource> {
    @Override
    public int weigh(Path p, Resource r) {
      return 2 * p.toString().length() + r.raw.length;
    }
  }
}
