// 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.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.gitiles.CommitData.Field;
import com.google.template.soy.data.LoggingAdvisingAppendable;
import com.google.template.soy.jbcsrc.api.SoySauce;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;

public class LogSoyData {
  private static final ImmutableSet<Field> FIELDS =
      Sets.immutableEnumSet(
          Field.ABBREV_SHA,
          Field.SHA,
          Field.URL,
          Field.SHORT_MESSAGE,
          Field.MESSAGE,
          Field.AUTHOR,
          Field.COMMITTER,
          Field.BRANCHES,
          Field.TAGS);
  private static final ImmutableSet<Field> VERBOSE_FIELDS = Field.setOf(FIELDS, Field.DIFF_TREE);

  /** Behavior for the footer link when rendering streaming log data. */
  public enum FooterBehavior {
    /** "Next" link that skips commits in the current view. */
    NEXT,

    /** "More" link that starts from HEAD. */
    LOG_HEAD;
  }

  private final HttpServletRequest req;
  private final GitilesView view;
  private final Set<Field> fields;
  private final String variant;
  private CommitSoyData csd;

  public LogSoyData(HttpServletRequest req, GitilesAccess access, String pretty)
      throws IOException {
    this.req = checkNotNull(req);
    this.view = checkNotNull(ViewFilter.getView(req));
    checkNotNull(pretty);
    Config config = access.getConfig();
    fields =
        config.getBoolean("logFormat", pretty, "verbose", false) || pretty.equals("fuller")
            ? VERBOSE_FIELDS
            : FIELDS;
    variant = firstNonNull(config.getString("logFormat", pretty, "variant"), pretty);
  }

  private void renderHtml(SoySauce.Renderer renderer, LoggingAdvisingAppendable out)
      throws IOException {
    if (!renderer.renderHtml(out).result().isDone()) {
      throw new IOException("failed to render HTML");
    }
  }

  public void renderStreaming(
      Paginator paginator,
      @Nullable String revision,
      Renderer renderer,
      Writer writer,
      DateFormatter df,
      FooterBehavior footerBehavior)
      throws IOException {
    LoggingAdvisingAppendable out = LoggingAdvisingAppendable.delegating(writer);
    renderHtml(
        renderer
            .newRenderer("com.google.gitiles.templates.LogDetail.logEntriesHeader")
            .setData(toHeaderSoyData(paginator, revision)),
        out);

    SoySauce.Renderer entryRenderer =
        renderer.newRenderer("com.google.gitiles.templates.LogDetail.logEntryWrapper");
    boolean renderedEntries = false;
    for (RevCommit c : paginator) {
      renderHtml(entryRenderer.setData(toEntrySoyData(paginator, c, df)), out);
      renderedEntries = true;
    }
    if (!renderedEntries) {
      renderHtml(renderer.newRenderer("com.google.gitiles.templates.LogDetail.emptyLog"), out);
    }

    renderHtml(
        renderer
            .newRenderer("com.google.gitiles.templates.LogDetail.logEntriesFooter")
            .setData(toFooterSoyData(paginator, revision, footerBehavior)),
        out);
  }

  private Map<String, Object> toHeaderSoyData(Paginator paginator, @Nullable String revision) {
    Map<String, Object> data = Maps.newHashMapWithExpectedSize(1);
    ObjectId prev = paginator.getPreviousStart();
    if (prev != null) {
      GitilesView.Builder prevView = copyAndCanonicalizeView(revision);
      if (prevView.getRevision().getId().equals(prev)) {
        prevView.removeParam(LogServlet.START_PARAM);
      } else {
        prevView.replaceParam(LogServlet.START_PARAM, prev.name());
      }
      data.put("previousUrl", prevView.toUrl());
    }
    return data;
  }

  private Map<String, Object> toEntrySoyData(Paginator paginator, RevCommit c, DateFormatter df)
      throws IOException {
    if (csd == null) {
      csd = new CommitSoyData();
    }

    Map<String, Object> entry = csd.toSoyData(req, paginator.getWalk(), c, fields, df);
    DiffEntry rename = paginator.getRename(c);
    if (rename != null) {
      entry.put("rename", toRenameSoyData(rename));
    }
    return ImmutableMap.of(
        "variant", variant,
        "entry", entry);
  }

  private @Nullable Map<String, Object> toRenameSoyData(DiffEntry entry) {
    if (entry == null) {
      return null;
    }
    ChangeType type = entry.getChangeType();
    if (type != ChangeType.RENAME && type != ChangeType.COPY) {
      return null;
    }
    return ImmutableMap.<String, Object>of(
        "changeType", type.toString(),
        "oldPath", entry.getOldPath(),
        "newPath", entry.getNewPath(),
        "score", entry.getScore());
  }

  private Map<String, Object> toFooterSoyData(
      Paginator paginator, @Nullable String revision, FooterBehavior behavior) {
    switch (behavior) {
      case NEXT:
        ObjectId next = paginator.getNextStart();
        if (next == null) {
          return ImmutableMap.of();
        }
        return ImmutableMap.of(
            "nextUrl",
            copyAndCanonicalizeView(revision)
                .replaceParam(LogServlet.START_PARAM, next.name())
                .toUrl(),
            "nextText",
            "Next");

      case LOG_HEAD:
        return ImmutableMap.of(
            "nextUrl", GitilesView.log().copyFrom(view).toUrl(), "nextText", "More");
      default:
        throw new IllegalStateException("unknown footer behavior: " + behavior);
    }
  }

  private GitilesView.Builder copyAndCanonicalizeView(String revision) {
    // Canonicalize the view by using full SHAs.
    GitilesView.Builder copy = GitilesView.log().copyFrom(view);
    if (!Revision.isNull(view.getRevision())) {
      copy.setRevision(view.getRevision());
    } else if (revision != null) {
      copy.setRevision(Revision.named(revision));
    } else {
      copy.setRevision(Revision.NULL);
    }
    if (!Revision.isNull(view.getOldRevision())) {
      copy.setOldRevision(view.getOldRevision());
    }
    return copy;
  }
}
