// 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) ? 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("gitiles.logEntriesHeader")
            .setData(toHeaderSoyData(paginator, revision)),
        out);

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

    renderHtml(
        renderer
            .newRenderer("gitiles.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.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 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;
  }
}
