// 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 com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.changes.PatchTable;
import com.google.gerrit.client.changes.PublishCommentScreen;
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.CommentPanel;
import com.google.gerrit.client.ui.NavigationTable;
import com.google.gerrit.client.ui.NeedsSignInKeyCommand;
import com.google.gerrit.common.data.AccountInfo;
import com.google.gerrit.common.data.AccountInfoCache;
import com.google.gerrit.common.data.CommentDetail;
import com.google.gerrit.common.data.PatchScript;
import com.google.gerrit.prettify.common.SparseFileContent;
import com.google.gerrit.reviewdb.Patch;
import com.google.gerrit.reviewdb.PatchLineComment;
import com.google.gerrit.reviewdb.PatchSet;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Focusable;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwtexpui.globalkey.client.GlobalKey;
import com.google.gwtexpui.globalkey.client.KeyCommand;
import com.google.gwtexpui.globalkey.client.KeyCommandSet;

import java.util.ArrayList;
import java.util.List;

public abstract class AbstractPatchContentTable extends NavigationTable<Object>
    implements CommentEditorContainer, FocusHandler, BlurHandler {
  protected PatchTable fileList;
  protected AccountInfoCache accountCache = AccountInfoCache.empty();
  protected Patch.Key patchKey;
  protected PatchSet.Id idSideA;
  protected PatchSet.Id idSideB;
  protected boolean onlyOneHunk;

  private final KeyCommandSet keysComment;
  private HandlerRegistration regComment;
  private final KeyCommandSet keysOpenByEnter;
  private HandlerRegistration regOpenByEnter;

  protected AbstractPatchContentTable() {
    keysNavigation.add(new PrevKeyCommand(0, 'k', PatchUtil.C.linePrev()));
    keysNavigation.add(new NextKeyCommand(0, 'j', PatchUtil.C.lineNext()));
    keysNavigation.add(new PrevChunkKeyCmd(0, 'p', PatchUtil.C.chunkPrev()));
    keysNavigation.add(new NextChunkKeyCmd(0, 'n', PatchUtil.C.chunkNext()));
    keysNavigation.add(new PrevCommentCmd(0, 'P', PatchUtil.C.commentPrev()));
    keysNavigation.add(new NextCommentCmd(0, 'N', PatchUtil.C.commentNext()));

    keysAction.add(new OpenKeyCommand(0, 'o', PatchUtil.C.expandComment()));
    keysOpenByEnter = new KeyCommandSet(Gerrit.C.sectionNavigation());
    keysOpenByEnter.add(new OpenKeyCommand(0, KeyCodes.KEY_ENTER, PatchUtil.C.expandComment()));

    if (Gerrit.isSignedIn()) {
      keysAction.add(new InsertCommentCommand(0, 'c', PatchUtil.C
          .commentInsert()));
      keysAction.add(new PublishCommentsKeyCommand(0, 'r', Util.C
          .keyPublishComments()));

      // See CommentEditorPanel
      //
      keysComment = new KeyCommandSet(PatchUtil.C.commentEditorSet());
      keysComment.add(new NoOpKeyCommand(KeyCommand.M_CTRL, 's', PatchUtil.C
          .commentSaveDraft()));
      keysComment.add(new NoOpKeyCommand(0, KeyCodes.KEY_ESCAPE, PatchUtil.C
          .commentCancelEdit()));
    } else {
      keysComment = null;
    }

    table.setStyleName(Gerrit.RESOURCES.css().patchContentTable());
  }

  public void notifyDraftDelta(final int delta) {
    if (fileList != null) {
      fileList.notifyDraftDelta(patchKey, delta);
    }

    Widget p = getParent();
    while (p != null) {
      if (p instanceof CommentEditorContainer) {
        ((CommentEditorContainer) p).notifyDraftDelta(delta);
        break;
      }
      p = p.getParent();
    }
  }

  @Override
  public void remove(CommentEditorPanel panel) {
    final int nRows = table.getRowCount();
    for (int row = 0; row < nRows; row++) {
      final int nCells = table.getCellCount(row);
      for (int cell = 0; cell < nCells; cell++) {
        if (table.getWidget(row, cell) == panel) {
          destroyEditor(row, cell);
          Widget p = table;
          while (p != null) {
            if (p instanceof Focusable) {
              ((Focusable) p).setFocus(true);
              break;
            }
            p = p.getParent();
          }

          if (Gerrit.RESOURCES.css().commentHolder().equals(
              table.getCellFormatter().getStyleName(row - 1, cell))) {
            table.getCellFormatter().addStyleName(row - 1, cell,
                Gerrit.RESOURCES.css().commentPanelLast());
          }
          return;
        }
      }
    }
  }

  @Override
  public void setRegisterKeys(final boolean on) {
    super.setRegisterKeys(on);
    if (on && keysComment != null && regComment == null) {
      regComment = GlobalKey.add(this, keysComment);
    } else if (!on && regComment != null) {
      regComment.removeHandler();
      regComment = null;
    }

    if (on && keysOpenByEnter != null && regOpenByEnter == null) {
      regOpenByEnter = GlobalKey.add(this, keysOpenByEnter);
    } else if (!on && regOpenByEnter != null) {
      regOpenByEnter.removeHandler();
      regOpenByEnter = null;
    }
  }

  public void display(final Patch.Key k, final PatchSet.Id a,
      final PatchSet.Id b, final PatchScript s) {
    patchKey = k;
    idSideA = a;
    idSideB = b;

    render(s);
  }

  protected abstract void render(PatchScript script);

  protected abstract void onInsertComment(PatchLine pl);

  public abstract void display(CommentDetail comments);

  @Override
  protected MyFlexTable createFlexTable() {
    return new DoubleClickFlexTable();
  }

  @Override
  protected Object getRowItemKey(final Object item) {
    return null;
  }

  protected void initScript(final PatchScript script) {
    if (script.getEdits().size() == 1) {
      final SparseFileContent a = script.getA();
      final SparseFileContent b = script.getB();
      onlyOneHunk = a.size() == 0 || b.size() == 0;
    } else {
      onlyOneHunk = false;
    }
  }

  private boolean isChunk(final int row) {
    final Object o = getRowItem(row);
    if (!onlyOneHunk && o instanceof PatchLine) {
      final PatchLine pl = (PatchLine) o;
      switch (pl.getType()) {
        case DELETE:
        case INSERT:
        case REPLACE:
          return true;
      }
    } else if (o instanceof CommentList) {
      return true;
    }
    return false;
  }

  private int findChunkStart(int row) {
    while (0 <= row && isChunk(row)) {
      row--;
    }
    return row + 1;
  }

  private int findChunkEnd(int row) {
    final int max = table.getRowCount();
    while (row < max && isChunk(row)) {
      row++;
    }
    return row - 1;
  }

  private static int oneBefore(final int begin) {
    return 1 <= begin ? begin - 1 : begin;
  }

  private int oneAfter(final int end) {
    return end + 1 < table.getRowCount() ? end + 1 : end;
  }

  private void moveToPrevChunk(int row) {
    while (0 <= row && isChunk(row)) {
      row--;
    }
    for (; 0 <= row; row--) {
      if (isChunk(row)) {
        final int start = findChunkStart(row);
        movePointerTo(start, false);
        scrollIntoView(oneBefore(start), oneAfter(row));
        return;
      }
    }

    // No prior hunk found? Try to hit the first line in the file.
    //
    for (row = 0; row < table.getRowCount(); row++) {
      if (getRowItem(row) != null) {
        movePointerTo(row);
        break;
      }
    }
  }

  private void moveToNextChunk(int row) {
    final int max = table.getRowCount();
    while (row < max && isChunk(row)) {
      row++;
    }
    for (; row < max; row++) {
      if (isChunk(row)) {
        movePointerTo(row, false);
        scrollIntoView(oneBefore(row), oneAfter(findChunkEnd(row)));
        return;
      }
    }

    // No next hunk found? Try to hit the last line in the file.
    //
    for (row = max - 1; row >= 0; row--) {
      if (getRowItem(row) != null) {
        movePointerTo(row);
        break;
      }
    }
  }

  private void moveToPrevComment(int row) {
    while (0 <= row && isComment(row)) {
      row--;
    }
    for (; 0 <= row; row--) {
      if (isComment(row)) {
        movePointerTo(row, false);
        scrollIntoView(oneBefore(row), oneAfter(row));
        return;
      }
    }

    // No prior comment found? Try to hit the first line in the file.
    //
    for (row = 0; row < table.getRowCount(); row++) {
      if (getRowItem(row) != null) {
        movePointerTo(row);
        break;
      }
    }
  }

  private void moveToNextComment(int row) {
    final int max = table.getRowCount();
    while (row < max && isComment(row)) {
      row++;
    }
    for (; row < max; row++) {
      if (isComment(row)) {
        movePointerTo(row, false);
        scrollIntoView(oneBefore(row), oneAfter(row));
        return;
      }
    }

    // No next comment found? Try to hit the last line in the file.
    //
    for (row = max - 1; row >= 0; row--) {
      if (getRowItem(row) != null) {
        movePointerTo(row);
        break;
      }
    }
  }

  private boolean isComment(int row) {
    return getRowItem(row) instanceof CommentList;
  }

  /** Invoked when the user clicks on a table cell. */
  protected abstract void onCellDoubleClick(int row, int column);

  /**
   * Invokes createCommentEditor() with an empty string as value for the comment
   * parent UUID. This method is invoked by callers that want to create an
   * editor for a comment that is not a reply.
   */
  protected void createCommentEditor(final int suggestRow, final int column,
      final int line, final short file) {
    if (Gerrit.isSignedIn()) {
      if (1 <= line) {
        final Patch.Key parentKey;
        final short side;
        switch (file) {
          case 0:
            if (idSideA == null) {
              parentKey = new Patch.Key(idSideB, patchKey.get());
              side = (short) 0;
            } else {
              parentKey = new Patch.Key(idSideA, patchKey.get());
              side = (short) 1;
            }
            break;
          case 1:
            parentKey = new Patch.Key(idSideB, patchKey.get());
            side = (short) 1;
            break;
          default:
            throw new RuntimeException("unexpected file id " + file);
        }

        final PatchLineComment newComment =
            new PatchLineComment(new PatchLineComment.Key(parentKey, null),
                line, Gerrit.getUserAccount().getId(), null);
        newComment.setSide(side);
        newComment.setMessage("");

        createCommentEditor(suggestRow, column, newComment).setFocus(true);
      }
    } else {
      Gerrit.doSignIn(History.getToken());
    }
  }

  private CommentEditorPanel createCommentEditor(final int suggestRow,
      final int column, final PatchLineComment newComment) {
    int row = suggestRow;
    int spans[] = new int[column + 1];
    FIND_ROW: while (row < table.getRowCount()) {
      int col = 0;
      for (int cell = 0; row < table.getRowCount()
          && cell < table.getCellCount(row); cell++) {
        while (col < column && 0 < spans[col]) {
          spans[col++]--;
        }
        spans[col] = table.getFlexCellFormatter().getRowSpan(row, cell);
        if (col == column) {
          final Widget w = table.getWidget(row, cell);
          if (w instanceof CommentEditorPanel) {
            // Don't insert two editors on the same position, it doesn't make
            // any sense to the user.
            //
            return ((CommentEditorPanel) w);

          } else if (w instanceof CommentPanel) {
            if (newComment != null && newComment.getParentUuid() != null) {
              // If we are a reply, we were given the exact row to insert
              // ourselves at. We should be before this panel so break.
              //
              break FIND_ROW;
            }
            row++;
          } else {
            break FIND_ROW;
          }
        }
      }
    }

    if (newComment == null) {
      return null;
    }

    final CommentEditorPanel ed = new CommentEditorPanel(newComment);
    ed.addFocusHandler(this);
    ed.addBlurHandler(this);
    boolean isCommentRow = false;
    boolean needInsert = false;
    if (row < table.getRowCount()) {
      for (int cell = 0; cell < table.getCellCount(row); cell++) {
        final Widget w = table.getWidget(row, cell);
        if (w instanceof CommentEditorPanel || w instanceof CommentPanel) {
          if (column == cell) {
            needInsert = true;
          }
          isCommentRow = true;
        }
      }
    }
    if (needInsert || !isCommentRow) {
      insertRow(row);
      styleCommentRow(row);
    }
    table.setWidget(row, column, ed);
    styleLastCommentCell(row, column);

    int span = 1;
    for (int r = row + 1; r < table.getRowCount(); r++) {
      boolean hasComment = false;
      for (int c = 0; c < table.getCellCount(r); c++) {
        final Widget w = table.getWidget(r, c);
        if (w instanceof CommentPanel || w instanceof CommentEditorPanel) {
          if (c != column) {
            hasComment = true;
            break;
          }
        }
      }
      if (hasComment) {
        table.removeCell(r, column);
        span++;
      } else {
        break;
      }
    }
    if (span > 1) {
      table.getFlexCellFormatter().setRowSpan(row, column, span);
    }

    for (int r = row - 1; r > 0; r--) {
      if (getRowItem(r) instanceof CommentList) {
        continue;
      } else if (getRowItem(r) != null) {
        movePointerTo(r);
        break;
      }
    }

    return ed;
  }

  protected void insertRow(final int row) {
    table.insertRow(row);
    table.getCellFormatter().setStyleName(row, 0,
        Gerrit.RESOURCES.css().iconCell());
  }

  @Override
  protected void onOpenRow(final int row) {
    final Object item = getRowItem(row);
    if (item instanceof CommentList) {
      for (final CommentPanel p : ((CommentList) item).panels) {
        p.setOpen(!p.isOpen());
      }
    }
  }

  public void setAccountInfoCache(final AccountInfoCache aic) {
    assert aic != null;
    accountCache = aic;
  }

  private void destroyEditor(final int row, final int col) {
    table.clearCell(row, col);
    final int span = table.getFlexCellFormatter().getRowSpan(row, col);
    boolean removeRow = true;
    final int nCells = table.getCellCount(row);
    for (int cell = 0; cell < nCells; cell++) {
      if (table.getWidget(row, cell) != null) {
        removeRow = false;
        break;
      }
    }
    if (removeRow) {
      for (int r = row - 1; 0 <= r; r--) {
        boolean data = false;
        for (int c = 0; c < table.getCellCount(r); c++) {
          data |= table.getWidget(r, c) != null;
          final int s = table.getFlexCellFormatter().getRowSpan(r, c) - 1;
          if (r + s == row) {
            table.getFlexCellFormatter().setRowSpan(r, c, s);
          }
        }
        if (!data) {
          break;
        }
      }
      table.removeRow(row);
    } else if (span != 1) {
      table.getFlexCellFormatter().setRowSpan(row, col, 1);
      for (int r = row + 1; r < row + span; r++) {
        table.insertCell(r, col + 1);
      }
    }
  }

  protected void bindComment(final int row, final int col,
      final PatchLineComment line, final boolean isLast) {
    if (line.getStatus() == PatchLineComment.Status.DRAFT) {
      final CommentEditorPanel plc = new CommentEditorPanel(line);
      plc.addFocusHandler(this);
      plc.addBlurHandler(this);
      table.setWidget(row, col, plc);
      styleLastCommentCell(row, col);

    } else {
      final AccountInfo author = accountCache.get(line.getAuthor());
      final PublishedCommentPanel panel =
          new PublishedCommentPanel(author, line);
      panel.addFocusHandler(this);
      panel.addBlurHandler(this);
      table.setWidget(row, col, panel);
      styleLastCommentCell(row, col);

      CommentList l = (CommentList) getRowItem(row);
      if (l == null) {
        l = new CommentList();
        setRowItem(row, l);
      }
      l.comments.add(line);
      l.panels.add(panel);
    }

    styleCommentRow(row);
  }

  @Override
  public void onFocus(FocusEvent event) {
    // when the comment panel gets focused (actually when a button inside the
    // comment panel gets focused) we have to unregister the key binding for
    // ENTER that expands/collapses the comment panel, if we don't do this the
    // focused button in the comment panel cannot be triggered by pressing ENTER
    // since ENTER would then be already consumed by this key binding
    if (regOpenByEnter != null) {
      regOpenByEnter.removeHandler();
      regOpenByEnter = null;
    }
  }

  @Override
  public void onBlur(BlurEvent event) {
    // when the comment panel gets blurred (actually when a button inside the
    // comment panel gets blurred) we have to re-register the key binding for
    // ENTER that expands/collapses the comment panel
    if (keysOpenByEnter != null && regOpenByEnter == null) {
      regOpenByEnter = GlobalKey.add(this, keysOpenByEnter);
    }
  }

  private void styleCommentRow(final int row) {
    final CellFormatter fmt = table.getCellFormatter();
    final Element iconCell = fmt.getElement(row, 0);
    UIObject.setStyleName(DOM.getParent(iconCell), Gerrit.RESOURCES.css()
        .commentHolder(), true);
  }

  private void styleLastCommentCell(final int row, final int col) {
    final CellFormatter fmt = table.getCellFormatter();
    fmt.removeStyleName(row - 1, col, //
        Gerrit.RESOURCES.css().commentPanelLast());
    fmt.setStyleName(row, col, Gerrit.RESOURCES.css().commentHolder());
    fmt.addStyleName(row, col, Gerrit.RESOURCES.css().commentPanelLast());
  }

  protected static class CommentList {
    final List<PatchLineComment> comments = new ArrayList<PatchLineComment>();
    final List<PublishedCommentPanel> panels =
        new ArrayList<PublishedCommentPanel>();
  }

  protected class DoubleClickFlexTable extends MyFlexTable {
    public DoubleClickFlexTable() {
      sinkEvents(Event.ONDBLCLICK | Event.ONCLICK);
    }

    @Override
    public void onBrowserEvent(final Event event) {
      switch (DOM.eventGetType(event)) {
        case Event.ONCLICK: {
          // Find out which cell was actually clicked.
          final Element td = getEventTargetCell(event);
          if (td == null) {
            break;
          }
          final int row = rowOf(td);
          if (getRowItem(row) != null) {
            movePointerTo(row);
            return;
          }
          break;
        }
        case Event.ONDBLCLICK: {
          // Find out which cell was actually clicked.
          Element td = getEventTargetCell(event);
          if (td == null) {
            return;
          }
          onCellDoubleClick(rowOf(td), columnOf(td));
          return;
        }
      }
      super.onBrowserEvent(event);
    }
  }

  public static class NoOpKeyCommand extends NeedsSignInKeyCommand {
    public NoOpKeyCommand(int mask, int key, String help) {
      super(mask, key, help);
    }

    @Override
    public void onKeyPress(final KeyPressEvent event) {
    }
  }

  public class InsertCommentCommand extends NeedsSignInKeyCommand {
    public InsertCommentCommand(int mask, int key, String help) {
      super(mask, key, help);
    }

    @Override
    public void onKeyPress(final KeyPressEvent event) {
      ensurePointerVisible();
      for (int row = getCurrentRow(); 0 <= row; row--) {
        final Object item = getRowItem(row);
        if (item instanceof PatchLine) {
          onInsertComment((PatchLine) item);
          return;
        } else if (item instanceof CommentList) {
          continue;
        } else {
          return;
        }
      }
    }
  }

  public class PublishCommentsKeyCommand extends NeedsSignInKeyCommand {
    public PublishCommentsKeyCommand(int mask, char key, String help) {
      super(mask, key, help);
    }

    @Override
    public void onKeyPress(final KeyPressEvent event) {
      final PatchSet.Id id = patchKey.getParentKey();
      Gerrit.display("change,publish," + id.toString(),
          new PublishCommentScreen(id));
    }
  }

  public class PrevChunkKeyCmd extends KeyCommand {
    public PrevChunkKeyCmd(int mask, int key, String help) {
      super(mask, key, help);
    }

    @Override
    public void onKeyPress(final KeyPressEvent event) {
      ensurePointerVisible();
      moveToPrevChunk(getCurrentRow());
    }
  }

  public class NextChunkKeyCmd extends KeyCommand {
    public NextChunkKeyCmd(int mask, int key, String help) {
      super(mask, key, help);
    }

    @Override
    public void onKeyPress(final KeyPressEvent event) {
      ensurePointerVisible();
      moveToNextChunk(getCurrentRow());
    }
  }

  public class PrevCommentCmd extends KeyCommand {
    public PrevCommentCmd(int mask, int key, String help) {
      super(mask, key, help);
    }

    @Override
    public void onKeyPress(final KeyPressEvent event) {
      ensurePointerVisible();
      moveToPrevComment(getCurrentRow());
    }
  }

  public class NextCommentCmd extends KeyCommand {
    public NextCommentCmd(int mask, int key, String help) {
      super(mask, key, help);
    }

    @Override
    public void onKeyPress(final KeyPressEvent event) {
      ensurePointerVisible();
      moveToNextComment(getCurrentRow());
    }
  }

  private class PublishedCommentPanel extends CommentPanel implements
      ClickHandler {
    final PatchLineComment comment;
    final Button reply;
    final Button replyDone;

    PublishedCommentPanel(final AccountInfo author, final PatchLineComment c) {
      super(author, c.getWrittenOn(), c.getMessage());
      this.comment = c;

      reply = new Button(PatchUtil.C.buttonReply());
      reply.addClickHandler(this);
      addButton(reply);

      replyDone = new Button(PatchUtil.C.buttonReplyDone());
      replyDone.addClickHandler(this);
      addButton(replyDone);
    }

    @Override
    public void onClick(final ClickEvent event) {
      if (Gerrit.isSignedIn()) {
        if (reply == event.getSource()) {
          createReplyEditor();
        } else if (replyDone == event.getSource()) {
          cannedReply(PatchUtil.C.cannedReplyDone());
        }

      } else {
        Gerrit.doSignIn(History.getToken());
      }
    }

    private void createReplyEditor() {
      final PatchLineComment newComment = newComment();
      newComment.setMessage("");
      createEditor(newComment).setFocus(true);
    }

    private void cannedReply(String message) {
      CommentEditorPanel p = createEditor(null);
      if (p == null) {
        final PatchLineComment newComment = newComment();
        newComment.setMessage(message);

        enableButtons(false);
        PatchUtil.DETAIL_SVC.saveDraft(newComment,
            new GerritCallback<PatchLineComment>() {
              public void onSuccess(final PatchLineComment result) {
                enableButtons(true);
                notifyDraftDelta(1);
                createEditor(result).setOpen(false);
              }

              @Override
              public void onFailure(Throwable caught) {
                enableButtons(true);
                super.onFailure(caught);
              }
            });
      } else {
        if (!p.isOpen()) {
          p.setOpen(true);
        }
        p.setFocus(true);
      }
    }

    private CommentEditorPanel createEditor(final PatchLineComment newComment) {
      int row = rowOf(getElement());
      int column = columnOf(getElement());
      return createCommentEditor(row + 1, column, newComment);
    }

    private PatchLineComment newComment() {
      PatchLineComment newComment =
          new PatchLineComment(new PatchLineComment.Key(comment.getKey()
              .getParentKey(), null), comment.getLine(), Gerrit
              .getUserAccount().getId(), comment.getKey().get());
      newComment.setSide(comment.getSide());
      return newComment;
    }
  }
}
