// Copyright (C) 2013 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.change;

import static com.google.gwt.event.dom.client.KeyCodes.KEY_ENTER;
import static com.google.gwt.event.dom.client.KeyCodes.KEY_MAC_ENTER;

import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.changes.ChangeApi;
import com.google.gerrit.client.changes.CommentInfo;
import com.google.gerrit.client.changes.ReviewInput;
import com.google.gerrit.client.changes.ReviewInput.DraftHandling;
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.info.ChangeInfo.ApprovalInfo;
import com.google.gerrit.client.info.ChangeInfo.LabelInfo;
import com.google.gerrit.client.info.ChangeInfo.MessageInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.LabelValue;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class ReplyBox extends Composite {
  interface Binder extends UiBinder<HTMLPanel, ReplyBox> {}

  private static final Binder uiBinder = GWT.create(Binder.class);

  interface Styles extends CssResource {
    String label_name();

    String label_value();

    String label_help();
  }

  private final CommentLinkProcessor clp;
  private final PatchSet.Id psId;
  private final String revision;
  private ReviewInput in = ReviewInput.create();
  private int labelHelpColumn;
  private LocalComments lc;

  @UiField Styles style;
  @UiField TextArea message;
  @UiField Element labelsParent;
  @UiField Grid labelsTable;
  @UiField Button post;
  @UiField Button cancel;
  @UiField ScrollPanel commentsPanel;
  @UiField FlowPanel comments;

  ReplyBox(
      CommentLinkProcessor clp,
      PatchSet.Id psId,
      String revision,
      NativeMap<LabelInfo> all,
      NativeMap<JsArrayString> permitted) {
    this.clp = clp;
    this.psId = psId;
    this.revision = revision;
    this.lc = new LocalComments(psId.getParentKey());
    initWidget(uiBinder.createAndBindUi(this));

    List<String> names = new ArrayList<>(permitted.keySet());
    if (names.isEmpty()) {
      UIObject.setVisible(labelsParent, false);
    } else {
      Collections.sort(names);
      renderLabels(names, all, permitted);
    }

    addDomHandler(
        new KeyDownHandler() {
          @Override
          public void onKeyDown(KeyDownEvent e) {
            e.stopPropagation();
            if ((e.getNativeKeyCode() == KEY_ENTER || e.getNativeKeyCode() == KEY_MAC_ENTER)
                && (e.isControlKeyDown() || e.isMetaKeyDown())) {
              e.preventDefault();
              if (post.isEnabled()) {
                onPost(null);
              }
            }
          }
        },
        KeyDownEvent.getType());
    addDomHandler(
        new KeyPressHandler() {
          @Override
          public void onKeyPress(KeyPressEvent e) {
            e.stopPropagation();
          }
        },
        KeyPressEvent.getType());
  }

  @Override
  protected void onLoad() {
    commentsPanel.setVisible(false);
    post.setEnabled(false);
    if (lc.hasReplyComment()) {
      message.setText(lc.getReplyComment());
      lc.removeReplyComment();
    }
    ChangeApi.drafts(psId.getParentKey().get())
        .get(
            new AsyncCallback<NativeMap<JsArray<CommentInfo>>>() {
              @Override
              public void onSuccess(NativeMap<JsArray<CommentInfo>> result) {
                displayComments(result);
                post.setEnabled(true);
              }

              @Override
              public void onFailure(Throwable caught) {
                post.setEnabled(true);
              }
            });

    Scheduler.get()
        .scheduleDeferred(
            new ScheduledCommand() {
              @Override
              public void execute() {
                message.setFocus(true);
              }
            });
    Scheduler.get()
        .scheduleFixedDelay(
            new RepeatingCommand() {
              @Override
              public boolean execute() {
                String t = message.getText();
                if (t != null) {
                  message.setCursorPos(t.length());
                }
                return false;
              }
            },
            0);
  }

  @UiHandler("post")
  void onPost(@SuppressWarnings("unused") ClickEvent e) {
    postReview();
  }

  void quickApprove(ReviewInput quickApproveInput) {
    in.mergeLabels(quickApproveInput);
    postReview();
  }

  boolean hasMessage() {
    return !message.getText().trim().isEmpty();
  }

  private void postReview() {
    in.message(message.getText().trim());
    // Don't send any comments in the request; just publish everything, even if
    // e.g. a draft was modified in another tab since we last looked it up.
    in.drafts(DraftHandling.PUBLISH_ALL_REVISIONS);
    in.prePost();
    ChangeApi.revision(psId.getParentKey().get(), revision)
        .view("review")
        .post(
            in,
            new GerritCallback<ReviewInput>() {
              @Override
              public void onSuccess(ReviewInput result) {
                Gerrit.display(PageLinks.toChange(psId));
              }

              @Override
              public void onFailure(final Throwable caught) {
                if (RestApi.isNotSignedIn(caught)) {
                  lc.setReplyComment(message.getText());
                }
                super.onFailure(caught);
              }
            });
    hide();
  }

  @UiHandler("cancel")
  void onCancel(@SuppressWarnings("unused") ClickEvent e) {
    message.setText("");
    hide();
  }

  void replyTo(MessageInfo msg) {
    if (msg.message() != null) {
      String t = message.getText();
      String m = quote(removePatchSetHeaderLine(msg.message()));
      if (t == null || t.isEmpty()) {
        t = m;
      } else if (t.endsWith("\n\n")) {
        t += m;
      } else if (t.endsWith("\n")) {
        t += "\n" + m;
      } else {
        t += "\n\n" + m;
      }
      message.setText(t);
    }
  }

  private static String removePatchSetHeaderLine(String msg) {
    msg = msg.trim();
    if (msg.startsWith("Patch Set ")) {
      int i = msg.indexOf('\n');
      if (i > 0) {
        msg = msg.substring(i + 1).trim();
      }
    }
    return msg;
  }

  public static String quote(String msg) {
    msg = msg.trim();
    StringBuilder quotedMsg = new StringBuilder();
    for (String line : msg.split("\\n")) {
      line = line.trim();
      while (line.length() > 67) {
        int i = line.lastIndexOf(' ', 67);
        if (i < 50) {
          i = line.indexOf(' ', 67);
        }
        if (i > 0) {
          quotedMsg.append(" > ").append(line.substring(0, i)).append("\n");
          line = line.substring(i + 1);
        } else {
          break;
        }
      }
      quotedMsg.append(" > ").append(line).append("\n");
    }
    quotedMsg.append("\n");
    return quotedMsg.toString();
  }

  private void hide() {
    for (Widget w = getParent(); w != null; w = w.getParent()) {
      if (w instanceof PopupPanel) {
        ((PopupPanel) w).hide();
        break;
      }
    }
  }

  private void renderLabels(
      List<String> names, NativeMap<LabelInfo> all, NativeMap<JsArrayString> permitted) {
    TreeSet<Short> values = new TreeSet<>();
    List<LabelAndValues> labels = new ArrayList<>(permitted.size());
    for (String id : names) {
      JsArrayString p = permitted.get(id);
      if (p != null) {
        if (!all.containsKey(id)) {
          continue;
        }
        Set<Short> a = new TreeSet<>();
        for (int i = 0; i < p.length(); i++) {
          a.add(LabelInfo.parseValue(p.get(i)));
        }
        labels.add(new LabelAndValues(all.get(id), a));
        values.addAll(a);
      }
    }
    List<Short> columns = new ArrayList<>(values);

    labelsTable.resize(1 + labels.size(), 2 + values.size());
    for (int c = 0; c < columns.size(); c++) {
      labelsTable.setText(0, 1 + c, LabelValue.formatValue(columns.get(c)));
      labelsTable.getCellFormatter().setStyleName(0, 1 + c, style.label_value());
    }

    List<LabelAndValues> checkboxes = new ArrayList<>(labels.size());
    int row = 1;
    for (LabelAndValues lv : labels) {
      if (isCheckBox(lv.info.valueSet())) {
        checkboxes.add(lv);
      } else {
        renderRadio(row++, columns, lv);
      }
    }
    for (LabelAndValues lv : checkboxes) {
      renderCheckBox(row++, lv);
    }
  }

  private Short normalizeDefaultValue(Short defaultValue, Set<Short> permittedValues) {
    Short pmin = Collections.min(permittedValues);
    Short pmax = Collections.max(permittedValues);
    Short dv = defaultValue;
    if (dv > pmax) {
      dv = pmax;
    } else if (dv < pmin) {
      dv = pmin;
    }
    return dv;
  }

  private void renderRadio(int row, List<Short> columns, LabelAndValues lv) {
    String id = lv.info.name();
    Short dv = normalizeDefaultValue(lv.info.defaultValue(), lv.permitted);

    labelHelpColumn = 1 + columns.size();
    labelsTable.setText(row, 0, id);

    CellFormatter fmt = labelsTable.getCellFormatter();
    fmt.setStyleName(row, 0, style.label_name());
    fmt.setStyleName(row, labelHelpColumn, style.label_help());

    ApprovalInfo self =
        Gerrit.isSignedIn() ? lv.info.forUser(Gerrit.getUserAccount().getId().get()) : null;

    final LabelRadioGroup group = new LabelRadioGroup(row, id, lv.permitted.size());
    for (int i = 0; i < columns.size(); i++) {
      Short v = columns.get(i);
      if (lv.permitted.contains(v)) {
        String text = lv.info.valueText(LabelValue.formatValue(v));
        LabelRadioButton b = new LabelRadioButton(group, text, v);
        if ((self != null && v == self.value()) || (self == null && v.equals(dv))) {
          b.setValue(true);
          group.select(b);
          in.label(group.label, v);
          labelsTable.setText(row, labelHelpColumn, b.text);
        }
        group.buttons.add(b);
        labelsTable.setWidget(row, 1 + i, b);
      }
    }
  }

  private void renderCheckBox(int row, LabelAndValues lv) {
    ApprovalInfo self =
        Gerrit.isSignedIn() ? lv.info.forUser(Gerrit.getUserAccount().getId().get()) : null;

    final String id = lv.info.name();
    final CheckBox b = new CheckBox();
    b.setText(id);
    b.setEnabled(lv.permitted.contains((short) 1));
    if (self != null && self.value() == 1) {
      b.setValue(true);
    }
    b.addValueChangeHandler(
        new ValueChangeHandler<Boolean>() {
          @Override
          public void onValueChange(ValueChangeEvent<Boolean> event) {
            in.label(id, event.getValue() ? (short) 1 : (short) 0);
          }
        });
    b.setStyleName(style.label_name());
    labelsTable.setWidget(row, 0, b);

    CellFormatter fmt = labelsTable.getCellFormatter();
    fmt.setStyleName(row, labelHelpColumn, style.label_help());
    labelsTable.setText(row, labelHelpColumn, lv.info.valueText("+1"));
  }

  private static boolean isCheckBox(Set<Short> values) {
    return values.size() == 2 && values.contains((short) 0) && values.contains((short) 1);
  }

  private void displayComments(NativeMap<JsArray<CommentInfo>> m) {
    comments.clear();

    JsArray<CommentInfo> l = m.get(Patch.COMMIT_MSG);
    if (l != null) {
      comments.add(
          new FileComments(clp, psId, Util.C.commitMessage(), copyPath(Patch.COMMIT_MSG, l)));
    }
    l = m.get(Patch.MERGE_LIST);
    if (l != null) {
      comments.add(
          new FileComments(clp, psId, Util.C.commitMessage(), copyPath(Patch.MERGE_LIST, l)));
    }

    List<String> paths = new ArrayList<>(m.keySet());
    Collections.sort(paths);

    for (String path : paths) {
      if (!Patch.isMagic(path)) {
        comments.add(new FileComments(clp, psId, path, copyPath(path, m.get(path))));
      }
    }

    commentsPanel.setVisible(comments.getWidgetCount() > 0);
  }

  private static List<CommentInfo> copyPath(String path, JsArray<CommentInfo> l) {
    for (int i = 0; i < l.length(); i++) {
      l.get(i).path(path);
    }
    return Natives.asList(l);
  }

  private static class LabelAndValues {
    final LabelInfo info;
    final Set<Short> permitted;

    LabelAndValues(LabelInfo info, Set<Short> permitted) {
      this.info = info;
      this.permitted = permitted;
    }
  }

  private class LabelRadioGroup {
    final int row;
    final String label;
    final List<LabelRadioButton> buttons;
    LabelRadioButton selected;

    LabelRadioGroup(int row, String label, int cnt) {
      this.row = row;
      this.label = label;
      this.buttons = new ArrayList<>(cnt);
    }

    void select(LabelRadioButton b) {
      selected = b;
      labelsTable.setText(row, labelHelpColumn, b.text);
    }
  }

  private class LabelRadioButton extends RadioButton
      implements ValueChangeHandler<Boolean>, ClickHandler, MouseOverHandler, MouseOutHandler {
    private final LabelRadioGroup group;
    private final String text;
    private final short value;

    LabelRadioButton(LabelRadioGroup group, String text, short value) {
      super(group.label);
      this.group = group;
      this.text = text;
      this.value = value;
      addValueChangeHandler(this);
      addClickHandler(this);
      addMouseOverHandler(this);
      addMouseOutHandler(this);
    }

    @Override
    public void onValueChange(ValueChangeEvent<Boolean> event) {
      if (event.getValue()) {
        select();
      }
    }

    @Override
    public void onClick(ClickEvent event) {
      select();
    }

    void select() {
      group.select(this);
      in.label(group.label, value);
    }

    @Override
    public void onMouseOver(MouseOverEvent event) {
      labelsTable.setText(group.row, labelHelpColumn, text);
    }

    @Override
    public void onMouseOut(MouseOutEvent event) {
      LabelRadioButton b = group.selected;
      String s = b != null ? b.text : "";
      labelsTable.setText(group.row, labelHelpColumn, s);
    }
  }
}
