// Copyright 2012 Google Inc. All Rights Reserved.
//
// 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.gitiles;

import static com.google.common.base.Preconditions.checkNotNull;
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT;
import static org.eclipse.jgit.lib.Constants.OBJ_TAG;
import static org.eclipse.jgit.lib.Constants.OBJ_TREE;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.io.BaseEncoding;
import com.google.gitiles.CommitData.Field;
import com.google.gitiles.CommitJsonData.Commit;
import com.google.gitiles.DateFormatter.Format;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.http.server.ServletUtils;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevTag;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Serves an HTML page with detailed information about a ref. */
public class RevisionServlet extends BaseServlet {
  private static final ImmutableSet<Field> COMMIT_SOY_FIELDS =
      Field.setOf(CommitSoyData.DEFAULT_FIELDS, Field.DIFF_TREE);
  private static final ImmutableSet<Field> COMMIT_JSON_FIELDS =
      Field.setOf(CommitJsonData.DEFAULT_FIELDS, Field.DIFF_TREE);

  private static final long serialVersionUID = 1L;
  private static final Logger log = LoggerFactory.getLogger(RevisionServlet.class);

  private final Linkifier linkifier;

  public RevisionServlet(
      GitilesAccess.Factory accessFactory, Renderer renderer, Linkifier linkifier) {
    super(renderer, accessFactory);
    this.linkifier = checkNotNull(linkifier, "linkifier");
  }

  @Override
  protected void doGetHtml(HttpServletRequest req, HttpServletResponse res) throws IOException {
    GitilesView view = ViewFilter.getView(req);
    Repository repo = ServletUtils.getRepository(req);
    GitilesAccess access = getAccess(req);
    Config cfg = getAccess(req).getConfig();

    try (RevWalk walk = new RevWalk(repo)) {
      DateFormatter df = new DateFormatter(access, Format.DEFAULT);
      List<RevObject> objects = listObjects(walk, view.getRevision());
      List<Map<String, ?>> soyObjects = Lists.newArrayListWithCapacity(objects.size());
      boolean hasBlob = false;
      boolean hasReadme = false;

      // TODO(sop): Allow caching commits by SHA-1 when no S cookie is sent.
      for (RevObject obj : objects) {
        try {
          switch (obj.getType()) {
            case OBJ_COMMIT:
              soyObjects.add(
                  ImmutableMap.of(
                      "type",
                      Constants.TYPE_COMMIT,
                      "data",
                      new CommitSoyData()
                          .setLinkifier(linkifier)
                          .setArchiveFormat(getArchiveFormat(access))
                          .toSoyData(req, walk, (RevCommit) obj, COMMIT_SOY_FIELDS, df)));
              break;
            case OBJ_TREE:
              Map<String, Object> tree =
                  new TreeSoyData(
                          walk.getObjectReader(), view, cfg, (RevTree) obj, req.getRequestURI())
                      .toSoyData(obj);
              soyObjects.add(ImmutableMap.of("type", Constants.TYPE_TREE, "data", tree));
              hasReadme = tree.containsKey("readmeHtml");
              break;
            case OBJ_BLOB:
              soyObjects.add(
                  ImmutableMap.of(
                      "type",
                      Constants.TYPE_BLOB,
                      "data",
                      new BlobSoyData(walk.getObjectReader(), view).toSoyData(obj)));
              hasBlob = true;
              break;
            case OBJ_TAG:
              soyObjects.add(
                  ImmutableMap.of(
                      "type",
                      Constants.TYPE_TAG,
                      "data",
                      new TagSoyData(linkifier, req).toSoyData(walk, (RevTag) obj, df)));
              break;
            default:
              log.warn("Bad object type for {}: {}", ObjectId.toString(obj.getId()), obj.getType());
              res.setStatus(SC_NOT_FOUND);
              return;
          }
        } catch (MissingObjectException e) {
          log.warn("Missing object " + ObjectId.toString(obj.getId()), e);
          res.setStatus(SC_NOT_FOUND);
          return;
        } catch (IncorrectObjectTypeException e) {
          log.warn("Incorrect object type for " + ObjectId.toString(obj.getId()), e);
          res.setStatus(SC_NOT_FOUND);
          return;
        }
      }

      renderHtml(
          req,
          res,
          "gitiles.revisionDetail",
          ImmutableMap.of(
              "title", view.getRevision().getName(),
              "objects", soyObjects,
              "hasBlob", hasBlob,
              "hasReadme", hasReadme));
    }
  }

  @Override
  protected void doGetText(HttpServletRequest req, HttpServletResponse res) throws IOException {
    GitilesView view = ViewFilter.getView(req);
    Repository repo = ServletUtils.getRepository(req);
    try (ObjectReader reader = repo.newObjectReader()) {
      ObjectLoader loader = reader.open(view.getRevision().getId());
      if (loader.getType() != OBJ_COMMIT) {
        res.setStatus(SC_NOT_FOUND);
      } else {
        PathServlet.setTypeHeader(res, loader.getType());
        try (Writer writer = startRenderText(req, res);
            OutputStream out = BaseEncoding.base64().encodingStream(writer)) {
          loader.copyTo(out);
        }
      }
    }
  }

  @Override
  protected void doGetJson(HttpServletRequest req, HttpServletResponse res) throws IOException {
    GitilesView view = ViewFilter.getView(req);
    Repository repo = ServletUtils.getRepository(req);

    try (RevWalk walk = new RevWalk(repo)) {
      DateFormatter df = new DateFormatter(getAccess(req), Format.DEFAULT);
      RevObject obj = walk.parseAny(view.getRevision().getId());
      switch (obj.getType()) {
        case OBJ_COMMIT:
          renderJson(
              req,
              res,
              new CommitJsonData().toJsonData(req, walk, (RevCommit) obj, COMMIT_JSON_FIELDS, df),
              Commit.class);
          break;
        default:
          // TODO(dborowitz): Support showing other types.
          res.setStatus(SC_NOT_FOUND);
          break;
      }
    }
  }

  // TODO(dborowitz): Extract this.
  static List<RevObject> listObjects(RevWalk walk, Revision rev)
      throws MissingObjectException, IOException {
    List<RevObject> objects = Lists.newArrayListWithExpectedSize(1);
    ObjectId id = rev.getId();
    RevObject cur;
    while (true) {
      cur = walk.parseAny(id);
      objects.add(cur);
      if (cur.getType() != Constants.OBJ_TAG) {
        break;
      }
      id = ((RevTag) cur).getObject();
    }
    if (cur.getType() == Constants.OBJ_COMMIT) {
      objects.add(walk.parseTree(((RevCommit) cur).getTree()));
    }
    return objects;
  }
}
