// 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 com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.changes.ChangeApi;
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.info.AccountInfo.AvatarInfo;
import com.google.gerrit.client.info.ChangeInfo;
import com.google.gerrit.client.info.ChangeInfo.ApprovalInfo;
import com.google.gerrit.client.info.ChangeInfo.LabelInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.LabelValue;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/** Displays a table of label and reviewer scores. */
class Labels extends Grid {
  private static final String DATA_ID = "data-id";
  private static final String DATA_VOTE = "data-vote";
  private static final String REMOVE_REVIEWER;
  private static final String REMOVE_VOTE;

  static {
    REMOVE_REVIEWER = DOM.createUniqueId().replace('-', '_');
    REMOVE_VOTE = DOM.createUniqueId().replace('-', '_');
    init(REMOVE_REVIEWER, REMOVE_VOTE);
  }

  private static native void init(String r, String v) /*-{
    $wnd[r] = $entry(function(e) {
      @com.google.gerrit.client.change.Labels::onRemoveReviewer(Lcom/google/gwt/dom/client/NativeEvent;)(e)
    });
    $wnd[v] = $entry(function(e) {
      @com.google.gerrit.client.change.Labels::onRemoveVote(Lcom/google/gwt/dom/client/NativeEvent;)(e)
    });
  }-*/;

  private static void onRemoveReviewer(NativeEvent event) {
    Integer user = getDataId(event);
    if (user != null) {
      final ChangeScreen screen = ChangeScreen.get(event);
      final Change.Id changeId = screen.getPatchSetId().getParentKey();
      ChangeApi.reviewer(changeId.get(), user).delete(
          new GerritCallback<JavaScriptObject>() {
            @Override
            public void onSuccess(JavaScriptObject result) {
              if (screen.isCurrentView()) {
                Gerrit.display(PageLinks.toChange(changeId));
              }
            }
          });
    }
  }

  private static void onRemoveVote(NativeEvent event) {
    Integer user = getDataId(event);
    String vote = getVoteId(event);
    if (user != null && vote != null) {
      final ChangeScreen screen = ChangeScreen.get(event);
      final Change.Id changeId = screen.getPatchSetId().getParentKey();
      ChangeApi.vote(changeId.get(), user, vote).delete(
          new GerritCallback<JavaScriptObject>() {
            @Override
            public void onSuccess(JavaScriptObject result) {
              if (screen.isCurrentView()) {
                Gerrit.display(PageLinks.toChange(changeId));
              }
            }
          });
    }
  }

  private static Integer getDataId(NativeEvent event) {
    Element e = event.getEventTarget().cast();
    while (e != null) {
      String v = e.getAttribute(DATA_ID);
      if (!v.isEmpty()) {
        return Integer.parseInt(v);
      }
      e = e.getParentElement();
    }
    return null;
  }

  private static String getVoteId(NativeEvent event) {
    Element e = event.getEventTarget().cast();
    while (e != null) {
      String v = e.getAttribute(DATA_VOTE);
      if (!v.isEmpty()) {
        return v;
      }
      e = e.getParentElement();
    }
    return null;
  }

  private ChangeScreen.Style style;

  void init(ChangeScreen.Style style) {
    this.style = style;
  }

  void set(ChangeInfo info) {
    List<String> names = new ArrayList<>(info.labels());
    Set<Integer> removable = info.removableReviewerIds();
    Collections.sort(names);

    resize(names.size(), 2);

    for (int row = 0; row < names.size(); row++) {
      String name = names.get(row);
      LabelInfo label = info.label(name);
      setText(row, 0, name);
      if (label.all() != null) {
        setWidget(row, 1, renderUsers(label, removable));
      }
      getCellFormatter().setStyleName(row, 0, style.labelName());
      getCellFormatter().addStyleName(row, 0, getStyleForLabel(label));
    }
  }

  private Widget renderUsers(LabelInfo label, Set<Integer> removable) {
    Map<Integer, List<ApprovalInfo>> m = new HashMap<>(4);
    int approved = 0;
    int rejected = 0;

    for (ApprovalInfo ai : Natives.asList(label.all())) {
      if (ai.value() != 0) {
        List<ApprovalInfo> l = m.get(Integer.valueOf(ai.value()));
        if (l == null) {
          l = new ArrayList<>(label.all().length());
          m.put(Integer.valueOf(ai.value()), l);
        }
        l.add(ai);

        if (isRejected(label, ai)) {
          rejected = ai.value();
        } else if (isApproved(label, ai)) {
          approved = ai.value();
        }
      }
    }

    SafeHtmlBuilder html = new SafeHtmlBuilder();
    for (Integer v : sort(m.keySet(), approved, rejected)) {
      if (!html.isEmpty()) {
        html.br();
      }

      String val = LabelValue.formatValue(v.shortValue());
      html.openSpan();
      html.setAttribute("title", label.valueText(val));
      if (v.intValue() == approved) {
        html.setStyleName(style.label_ok());
      } else if (v.intValue() == rejected) {
        html.setStyleName(style.label_reject());
      }
      html.append(val).append(" ");
      html.append(formatUserList(style, m.get(v), removable,
          label.name(), null));
      html.closeSpan();
    }
    return html.toBlockWidget();
  }

  private static List<Integer> sort(Set<Integer> keySet, int a, int b) {
    List<Integer> r = new ArrayList<>(keySet);
    Collections.sort(r);
    if (keySet.contains(a)) {
      r.remove(Integer.valueOf(a));
      r.add(0, a);
    } else if (keySet.contains(b)) {
      r.remove(Integer.valueOf(b));
      r.add(0, b);
    }
    return r;
  }

  private static boolean isApproved(LabelInfo label, ApprovalInfo ai) {
    return label.approved() != null
        && label.approved()._accountId() == ai._accountId();
  }

  private static boolean isRejected(LabelInfo label, ApprovalInfo ai) {
    return label.rejected() != null
        && label.rejected()._accountId() == ai._accountId();
  }

  private String getStyleForLabel(LabelInfo label) {
    switch (label.status()) {
      case OK:
        return style.label_ok();
      case NEED:
        return style.label_need();
      case REJECT:
      case IMPOSSIBLE:
        return style.label_reject();
      default:
      case MAY:
        return style.label_may();
    }
  }

  static SafeHtml formatUserList(ChangeScreen.Style style,
      Collection<? extends AccountInfo> in,
      Set<Integer> removable,
      String label,
      Map<Integer, VotableInfo> votable) {
    List<AccountInfo> users = new ArrayList<>(in);
    Collections.sort(users, new Comparator<AccountInfo>() {
      @Override
      public int compare(AccountInfo a, AccountInfo b) {
        String as = name(a);
        String bs = name(b);
        if (as.isEmpty()) {
          return 1;
        } else if (bs.isEmpty()) {
          return -1;
        }
        return as.compareTo(bs);
      }

      private String name(AccountInfo a) {
        if (a.name() != null) {
          return a.name();
        } else if (a.email() != null) {
          return a.email();
        }
        return "";
      }
    });

    SafeHtmlBuilder html = new SafeHtmlBuilder();
    Iterator<? extends AccountInfo> itr = users.iterator();
    while (itr.hasNext()) {
      AccountInfo ai = itr.next();
      AvatarInfo img = ai.avatar(AvatarInfo.DEFAULT_SIZE);
      String name;
      if (ai.name() != null) {
        name = ai.name();
      } else if (ai.email() != null) {
        name = ai.email();
      } else {
        name = Integer.toString(ai._accountId());
      }

      String votableCategories = "";
      if (votable != null) {
        VotableInfo vi = votable.get(ai._accountId());
        if (vi != null) {
          Set<String> s = vi.votableLabels();
          if (!s.isEmpty()) {
            StringBuilder sb = new StringBuilder(Util.C.votable());
            sb.append(" ");
            for (Iterator<String> it = vi.votableLabels().iterator();
                it.hasNext();) {
              sb.append(it.next());
              if (it.hasNext()) {
                sb.append(", ");
              }
            }
            votableCategories = sb.toString();
          }
        }
      }
      html.openSpan()
          .setAttribute("role", "listitem")
          .setAttribute(DATA_ID, ai._accountId())
          .setAttribute("title", getTitle(ai, votableCategories))
          .setStyleName(style.label_user());
      if (label != null) {
        html.setAttribute(DATA_VOTE, label);
      }
      if (img != null) {
        html.openElement("img")
            .setStyleName(style.avatar())
            .setAttribute("src", img.url());
        if (img.width() > 0) {
          html.setAttribute("width", img.width());
        }
        if (img.height() > 0) {
          html.setAttribute("height", img.height());
        }
        html.closeSelf();
      }
      html.append(name);
      if (removable.contains(ai._accountId())) {
        html.openElement("button");
        if (label != null) {
          html.setAttribute("title", Util.M.removeVote(label))
              .setAttribute("onclick", REMOVE_VOTE + "(event)");
        } else {
          html.setAttribute("title", Util.M.removeReviewer(name))
              .setAttribute("onclick", REMOVE_REVIEWER + "(event)");
        }
        html.append("×")
            .closeElement("button");
      }
      html.closeSpan();
      if (itr.hasNext()) {
        html.append(' ');
      }
    }
    return html;
  }

  private static String getTitle(AccountInfo ai, String votableCategories) {
    String title = ai.email() != null ? ai.email() : "";
    if (!votableCategories.isEmpty()) {
      if (!title.isEmpty()) {
        title += " ";
      }
      title += votableCategories;
    }
    return title;
  }
}
