// Copyright (C) 2014 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.googlesource.gerrit.plugins.imagare;

import static java.nio.charset.StandardCharsets.UTF_8;
import static javax.servlet.http.HttpServletResponse.SC_NOT_MODIFIED;

import com.google.common.base.CharMatcher;
import com.google.common.hash.Hashing;
import com.google.common.net.HttpHeaders;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.mime.FileTypeRegistry;
import com.google.gerrit.server.project.GetHead;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectResource;
import com.google.gerrit.server.project.ProjectState;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;

import eu.medsea.mimeutil.MimeType;

import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.errors.RevisionSyntaxException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathFilter;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

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

@Singleton
public class ImageServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;

  public  static final String PATH_PREFIX = "/project/";

  private final String pluginName;
  private final Provider<ReviewDb> db;
  private final ProjectControl.Factory projectControlFactory;
  private final ProjectCache projectCache;
  private final Provider<GetHead> getHead;
  private final GitRepositoryManager repoManager;
  private final FileTypeRegistry fileTypeRegistry;

  @Inject
  ImageServlet(
      @PluginName String pluginName,
      Provider<ReviewDb> db,
      ProjectControl.Factory projectControlFactory,
      ProjectCache projectCache,
      Provider<GetHead> getHead,
      GitRepositoryManager repoManager,
      FileTypeRegistry fileTypeRegistry) {
    this.pluginName = pluginName;
    this.db = db;
    this.projectControlFactory = projectControlFactory;
    this.projectCache = projectCache;
    this.getHead = getHead;
    this.repoManager = repoManager;
    this.fileTypeRegistry = fileTypeRegistry;
  }

  @Override
  public void service(HttpServletRequest req, HttpServletResponse res)
      throws IOException {
    if (!"GET".equals(req.getMethod()) && !"HEAD".equals(req.getMethod())) {
      CacheHeaders.setNotCacheable(res);
      res.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
      return;
    }

    ResourceKey key = ResourceKey.fromPath(getEncodedPath(req));
    ProjectState state = projectCache.get(key.project);
    if (state == null || key.file == null) {
      notFound(res);
      return;
    }

    MimeType mimeType = fileTypeRegistry.getMimeType(key.file, null);
    if (!("image".equals(mimeType.getMediaType())
          && fileTypeRegistry.isSafeInline(mimeType))) {
      notFound(res);
      return;
    }

    try {
      ProjectControl projectControl = projectControlFactory.validateFor(key.project);
      String rev = key.revision;
      if (rev == null || Constants.HEAD.equals(rev)) {
        rev = getHead.get().apply(new ProjectResource(projectControl));
      } else  {
        if (!ObjectId.isId(rev)) {
          if (!rev.startsWith(Constants.R_REFS)) {
            rev = Constants.R_HEADS + rev;
          }
          if (!projectControl.controlForRef(rev).isVisible()) {
            notFound(res);
            return;
          }
        }
      }
      try (Repository repo = repoManager.openRepository(key.project)) {
        ObjectId revId =
            repo.resolve(rev != null ? rev : Constants.HEAD);
        if (revId == null) {
          notFound(res);
          return;
        }

        if (ObjectId.isId(rev)) {
          try (RevWalk rw = new RevWalk(repo)) {
            RevCommit commit = rw.parseCommit(repo.resolve(rev));
            if (!projectControl.canReadCommit(db.get(), repo, commit)) {
              notFound(res);
              return;
            }
          }
        }

        String eTag = null;
        String receivedETag = req.getHeader(HttpHeaders.IF_NONE_MATCH);
        if (receivedETag != null) {
          eTag = computeETag(key.project, revId, key.file);
          if (eTag.equals(receivedETag)) {
            res.sendError(SC_NOT_MODIFIED);
            return;
          }
        }

        if (!"image".equals(mimeType.getMediaType())) {
          notFound(res);
          return;
        }

        try (RevWalk rw = new RevWalk(repo)) {
          RevCommit commit = rw.parseCommit(revId);
          RevTree tree = commit.getTree();
          try (TreeWalk tw = new TreeWalk(repo)) {
            tw.addTree(tree);
            tw.setRecursive(true);
            tw.setFilter(PathFilter.create(key.file));
            if (!tw.next()) {
              notFound(res);
              return;
            }
            ObjectId objectId = tw.getObjectId(0);
            ObjectLoader loader = repo.open(objectId);
            byte[] content = loader.getBytes(Integer.MAX_VALUE);

            mimeType = fileTypeRegistry.getMimeType(key.file, content);
            if (!"image".equals(mimeType.getMediaType())
                || !fileTypeRegistry.isSafeInline(mimeType)) {
              notFound(res);
              return;
            }
            res.setHeader(HttpHeaders.ETAG,
                eTag != null
                    ? eTag
                    : computeETag(key.project, revId, key.file));
            CacheHeaders.setCacheablePrivate(res, 7, TimeUnit.DAYS, false);
            send(req, res, content, mimeType.toString(), commit.getCommitTime());
            return;
          }
        } catch (IOException e) {
          notFound(res);
          return;
        }
      }
    } catch (RepositoryNotFoundException | NoSuchProjectException
        | ResourceNotFoundException | AuthException | RevisionSyntaxException e) {
      notFound(res);
      return;
    }
  }

  private String getEncodedPath(HttpServletRequest req) {
    String path = req.getRequestURI();
    String prefix = "/plugins/" + pluginName;
    if (path.startsWith(prefix)) {
      path = path.substring(prefix.length());
    }
    return path;
  }

  private static String computeETag(Project.NameKey project, ObjectId revId,
      String file) {
    return Hashing.md5().newHasher()
        .putUnencodedChars(project.get())
        .putUnencodedChars(revId.getName())
        .putUnencodedChars(file)
        .hash().toString();
  }

  private void send(HttpServletRequest req, HttpServletResponse res,
      byte[] content, String contentType, long lastModified) throws IOException {
    if (0 < lastModified) {
      long ifModifiedSince = req.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
      if (ifModifiedSince > 0 && ifModifiedSince == lastModified) {
        res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        return;
      } else {
        res.setDateHeader("Last-Modified", lastModified);
      }
    }
    res.setContentType(contentType);
    res.setCharacterEncoding(UTF_8.name());
    res.setContentLength(content.length);
    res.getOutputStream().write(content);
  }

  private static void notFound(HttpServletResponse res) throws IOException {
    CacheHeaders.setNotCacheable(res);
    res.sendError(HttpServletResponse.SC_NOT_FOUND);
  }

  private static class ResourceKey {
    final Project.NameKey project;
    final String file;
    final String revision;

    static ResourceKey fromPath(String path) {
      String project;
      String file = null;
      String revision = null;

      if (!path.startsWith(PATH_PREFIX)) {
        // should not happen since this servlet is only registered to handle
        // paths that start with this prefix
        throw new IllegalStateException("path must start with '" + PATH_PREFIX + "'");
      }
      path = path.substring(PATH_PREFIX.length());

      int i = path.indexOf('/');
      if (i != -1 && i != path.length() - 1) {
        project = IdString.fromUrl(path.substring(0, i)).get();
        String rest = path.substring(i + 1);

        if (rest.startsWith("rev/")) {
          if (rest.length() > 4) {
            rest = rest.substring(4);
            i = rest.indexOf('/');
            if (i != -1 && i != path.length() - 1) {
              revision = IdString.fromUrl(rest.substring(0, i)).get();
              file = IdString.fromUrl(rest.substring(i + 1)).get();
            } else {
              revision = IdString.fromUrl(rest).get();
            }
          }
        } else {
          file = IdString.fromUrl(rest).get();
        }

      } else {
        project = IdString.fromUrl(CharMatcher.is('/').trimTrailingFrom(path)).get();
      }

      return new ResourceKey(project, file, revision);
    }

    private ResourceKey(String p, String f, String r) {
      project = new Project.NameKey(p);
      file = f;
      revision = r;
    }
  }
}
