// Copyright (C) 2008 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.client.patches;

import static com.google.gerrit.client.patches.PatchLine.Type.CONTEXT;
import static com.google.gerrit.client.patches.PatchLine.Type.DELETE;
import static com.google.gerrit.client.patches.PatchLine.Type.INSERT;

import com.google.gerrit.client.Gerrit;
import com.google.gerrit.common.data.CommentDetail;
import com.google.gerrit.common.data.PatchScript;
import com.google.gerrit.common.data.PatchScript.DisplayMethod;
import com.google.gerrit.prettify.common.EditList;
import com.google.gerrit.prettify.common.SparseHtmlFile;
import com.google.gerrit.prettify.common.EditList.Hunk;
import com.google.gerrit.reviewdb.Patch;
import com.google.gerrit.reviewdb.PatchLineComment;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
import com.google.gwtorm.client.KeyUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

public class UnifiedDiffTable extends AbstractPatchContentTable {
  private static final int PC = 3;
  private static final Comparator<PatchLineComment> BY_DATE =
      new Comparator<PatchLineComment>() {
        public int compare(final PatchLineComment o1, final PatchLineComment o2) {
          return o1.getWrittenOn().compareTo(o2.getWrittenOn());
        }
      };

  @Override
  protected void onCellDoubleClick(final int row, final int column) {
    if (getRowItem(row) instanceof PatchLine) {
      final PatchLine pl = (PatchLine) getRowItem(row);
      switch (pl.getType()) {
        case DELETE:
        case CONTEXT:
          createCommentEditor(row + 1, PC, pl.getLineA(), (short) 0);
          break;
        case INSERT:
          createCommentEditor(row + 1, PC, pl.getLineB(), (short) 1);
          break;
      }
    }
  }

  @Override
  protected void onInsertComment(final PatchLine pl) {
    final int row = getCurrentRow();
    switch (pl.getType()) {
      case DELETE:
      case CONTEXT:
        createCommentEditor(row + 1, PC, pl.getLineA(), (short) 0);
        break;
      case INSERT:
        createCommentEditor(row + 1, PC, pl.getLineB(), (short) 1);
        break;
    }
  }

  private void appendImgTag(SafeHtmlBuilder nc, String url) {
    nc.openElement("img");
    nc.setAttribute("src", url);
    nc.closeElement("img");
  }

  @Override
  protected void render(final PatchScript script) {
    final SparseHtmlFile a = script.getSparseHtmlFileA();
    final SparseHtmlFile b = script.getSparseHtmlFileB();
    final SafeHtmlBuilder nc = new SafeHtmlBuilder();

    // Display the patch header
    for (final String line : script.getPatchHeader()) {
      appendFileHeader(nc, line);
    }

    if (script.getDisplayMethodA() == DisplayMethod.IMG
        || script.getDisplayMethodB() == DisplayMethod.IMG) {
      final String rawBase = GWT.getHostPageBaseURL() + "cat/";

      nc.openTr();
      nc.setAttribute("valign", "center");
      nc.setAttribute("align", "center");

      nc.openTd();
      nc.nbsp();
      nc.closeTd();

      nc.openTd();
      nc.nbsp();
      nc.closeTd();

      nc.openTd();
      nc.nbsp();
      nc.closeTd();

      nc.openTd();
      if (script.getDisplayMethodA() == DisplayMethod.IMG) {
        if (idSideA == null) {
          appendImgTag(nc, rawBase + KeyUtil.encode(patchKey.toString()) + "^1");
        } else {
          Patch.Key k = new Patch.Key(idSideA, patchKey.get());
          appendImgTag(nc, rawBase + KeyUtil.encode(k.toString()) + "^0");
        }
      }
      if (script.getDisplayMethodB() == DisplayMethod.IMG) {
        appendImgTag(nc, rawBase + KeyUtil.encode(patchKey.toString()) + "^0");
      }
      nc.closeTd();

      nc.closeTr();
    }

    final boolean syntaxHighlighting =
        script.getSettings().getPrettySettings().isSyntaxHighlighting();
    final ArrayList<PatchLine> lines = new ArrayList<PatchLine>();
    for (final EditList.Hunk hunk : script.getHunks()) {
      appendHunkHeader(nc, hunk);
      while (hunk.next()) {
        if (hunk.isContextLine()) {
          openLine(nc);
          appendLineNumber(nc, hunk.getCurA());
          appendLineNumber(nc, hunk.getCurB());
          appendLineText(nc, false, CONTEXT, a, hunk.getCurA());
          closeLine(nc);
          hunk.incBoth();
          lines.add(new PatchLine(CONTEXT, hunk.getCurA(), hunk.getCurB()));

        } else if (hunk.isDeletedA()) {
          openLine(nc);
          appendLineNumber(nc, hunk.getCurA());
          padLineNumber(nc);
          appendLineText(nc, syntaxHighlighting, DELETE, a, hunk.getCurA());
          closeLine(nc);
          hunk.incA();
          lines.add(new PatchLine(DELETE, hunk.getCurA(), 0));
          if (a.size() == hunk.getCurA()
              && script.getA().isMissingNewlineAtEnd()) {
            appendNoLF(nc);
          }

        } else if (hunk.isInsertedB()) {
          openLine(nc);
          padLineNumber(nc);
          appendLineNumber(nc, hunk.getCurB());
          appendLineText(nc, syntaxHighlighting, INSERT, b, hunk.getCurB());
          closeLine(nc);
          hunk.incB();
          lines.add(new PatchLine(INSERT, 0, hunk.getCurB()));
          if (b.size() == hunk.getCurB()
              && script.getB().isMissingNewlineAtEnd()) {
            appendNoLF(nc);
          }
        }
      }
    }
    resetHtml(nc);
    initScript(script);

    int row = script.getPatchHeader().size();
    final CellFormatter fmt = table.getCellFormatter();
    final Iterator<PatchLine> iLine = lines.iterator();
    while (iLine.hasNext()) {
      final PatchLine l = iLine.next();
      final String n;
      switch (l.getType()) {
        case CONTEXT:
          n = Gerrit.RESOURCES.css().diffTextCONTEXT();
          break;
        case DELETE:
          n = Gerrit.RESOURCES.css().diffTextDELETE();
          break;
        case INSERT:
          n = Gerrit.RESOURCES.css().diffTextINSERT();
          break;
        default:
          continue;
      }
      while (!fmt.getStyleName(row, PC).contains(n)) {
        row++;
      }
      setRowItem(row++, l);
    }
  }

  @Override
  public void display(final CommentDetail cd) {
    if (cd.isEmpty()) {
      return;
    }
    setAccountInfoCache(cd.getAccounts());

    final ArrayList<PatchLineComment> all = new ArrayList<PatchLineComment>();
    for (int row = 0; row < table.getRowCount();) {
      if (getRowItem(row) instanceof PatchLine) {
        final PatchLine pLine = (PatchLine) getRowItem(row);
        final List<PatchLineComment> fora = cd.getForA(pLine.getLineA());
        final List<PatchLineComment> forb = cd.getForB(pLine.getLineB());
        row++;

        if (!fora.isEmpty() && !forb.isEmpty()) {
          all.clear();
          all.addAll(fora);
          all.addAll(forb);
          Collections.sort(all, BY_DATE);
          row = insert(all, row);

        } else if (!fora.isEmpty()) {
          row = insert(fora, row);

        } else if (!forb.isEmpty()) {
          row = insert(forb, row);
        }
      } else {
        row++;
      }
    }
  }


  @Override
  protected void insertRow(final int row) {
    super.insertRow(row);
    final CellFormatter fmt = table.getCellFormatter();
    fmt.addStyleName(row, PC - 2, Gerrit.RESOURCES.css().lineNumber());
    fmt.addStyleName(row, PC - 1, Gerrit.RESOURCES.css().lineNumber());
    fmt.addStyleName(row, PC, Gerrit.RESOURCES.css().diffText());
  }

  private int insert(final List<PatchLineComment> in, int row) {
    for (Iterator<PatchLineComment> ci = in.iterator(); ci.hasNext();) {
      final PatchLineComment c = ci.next();
      insertRow(row);
      bindComment(row, PC, c, !ci.hasNext());
      row++;
    }
    return row;
  }

  private void appendFileHeader(final SafeHtmlBuilder m, final String line) {
    openLine(m);
    padLineNumber(m);
    padLineNumber(m);

    m.openTd();
    m.addStyleName(Gerrit.RESOURCES.css().diffText());
    m.addStyleName(Gerrit.RESOURCES.css().diffTextFileHeader());
    m.append(line);
    m.closeTd();
    closeLine(m);
  }

  private void appendHunkHeader(final SafeHtmlBuilder m, final Hunk hunk) {
    openLine(m);
    padLineNumber(m);
    padLineNumber(m);

    m.openTd();
    m.addStyleName(Gerrit.RESOURCES.css().diffText());
    m.addStyleName(Gerrit.RESOURCES.css().diffTextHunkHeader());
    m.append("@@ -");
    appendRange(m, hunk.getCurA() + 1, hunk.getEndA() - hunk.getCurA());
    m.append(" +");
    appendRange(m, hunk.getCurB() + 1, hunk.getEndB() - hunk.getCurB());
    m.append(" @@");
    m.closeTd();

    closeLine(m);
  }

  private void appendRange(final SafeHtmlBuilder m, final int begin,
      final int cnt) {
    switch (cnt) {
      case 0:
        m.append(begin - 1);
        m.append(",0");
        break;

      case 1:
        m.append(begin);
        break;

      default:
        m.append(begin);
        m.append(',');
        m.append(cnt);
        break;
    }
  }

  private void appendLineText(final SafeHtmlBuilder m,
      boolean syntaxHighlighting, final PatchLine.Type type,
      final SparseHtmlFile src, final int i) {
    final SafeHtml text = src.getSafeHtmlLine(i);
    m.openTd();
    m.addStyleName(Gerrit.RESOURCES.css().diffText());
    switch (type) {
      case CONTEXT:
        m.addStyleName(Gerrit.RESOURCES.css().diffTextCONTEXT());
        m.nbsp();
        m.append(text);
        break;
      case DELETE:
        m.addStyleName(Gerrit.RESOURCES.css().diffTextDELETE());
        if (syntaxHighlighting) {
          m.addStyleName(Gerrit.RESOURCES.css().fileLineDELETE());
        }
        m.append("-");
        m.append(text);
        break;
      case INSERT:
        m.addStyleName(Gerrit.RESOURCES.css().diffTextINSERT());
        if (syntaxHighlighting) {
          m.addStyleName(Gerrit.RESOURCES.css().fileLineINSERT());
        }
        m.append("+");
        m.append(text);
        break;
    }
    m.closeTd();
  }

  private void appendNoLF(final SafeHtmlBuilder m) {
    openLine(m);
    padLineNumber(m);
    padLineNumber(m);
    m.openTd();
    m.addStyleName(Gerrit.RESOURCES.css().diffText());
    m.addStyleName(Gerrit.RESOURCES.css().diffTextNoLF());
    m.append("\\ No newline at end of file");
    m.closeTd();
    closeLine(m);
  }

  private void openLine(final SafeHtmlBuilder m) {
    m.openTr();
    m.setAttribute("valign", "top");
    m.openTd();
    m.setStyleName(Gerrit.RESOURCES.css().iconCell());
    m.closeTd();
  }

  private void closeLine(final SafeHtmlBuilder m) {
    m.closeTr();
  }

  private void padLineNumber(final SafeHtmlBuilder m) {
    m.openTd();
    m.setStyleName(Gerrit.RESOURCES.css().lineNumber());
    m.closeTd();
  }

  private void appendLineNumber(final SafeHtmlBuilder m, final int idx) {
    m.openTd();
    m.setStyleName(Gerrit.RESOURCES.css().lineNumber());
    m.append(idx + 1);
    m.closeTd();
  }
}
