// Copyright (C) 2014 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.info.ChangeInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
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.DOM;
import com.google.gwt.user.client.rpc.StatusCodeException;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.ImageResourceRenderer;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwtexpui.globalkey.client.NpTextBox;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
import java.util.Iterator;

public class Hashtags extends Composite {

  interface Binder extends UiBinder<HTMLPanel, Hashtags> {}

  private static final int VISIBLE_LENGTH = 55;
  private static final Binder uiBinder = GWT.create(Binder.class);
  private static final String REMOVE;
  private static final String DATA_ID = "data-id";

  private PatchSet.Id psId;
  private boolean canEdit;

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

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

  private static void onRemove(NativeEvent event) {
    String hashtags = getDataId(event);
    if (hashtags != null) {
      final ChangeScreen screen = ChangeScreen.get(event);
      final PatchSet.Id psId = screen.getPatchSetId();
      ChangeApi.hashtags(psId.getParentKey().get())
          .post(
              PostInput.create(null, hashtags),
              new GerritCallback<JavaScriptObject>() {
                @Override
                public void onSuccess(JavaScriptObject result) {
                  if (screen.isCurrentView()) {
                    Gerrit.display(PageLinks.toChange(psId));
                  }
                }
              });
    }
  }

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

  @UiField Element hashtagsText;
  @UiField Image addHashtagIcon;
  @UiField Element form;
  @UiField Element error;
  @UiField NpTextBox hashtagTextBox;

  private ChangeScreen.Style style;
  private Change.Id changeId;

  public Hashtags() {

    initWidget(uiBinder.createAndBindUi(this));

    hashtagTextBox.setVisibleLength(VISIBLE_LENGTH);
    hashtagTextBox.addKeyDownHandler(
        new KeyDownHandler() {
          @Override
          public void onKeyDown(KeyDownEvent e) {
            if (e.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
              onCancel(null);
            } else if (e.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
              onAdd(null);
            }
          }
        });

    addHashtagIcon.addDomHandler(
        new ClickHandler() {
          @Override
          public void onClick(ClickEvent event) {
            onOpenForm();
          }
        },
        ClickEvent.getType());
  }

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

  void set(ChangeInfo info, String revision) {
    psId = new PatchSet.Id(info.legacyId(), info.revisions().get(revision)._number());

    canEdit = info.hasActions() && info.actions().containsKey("hashtags");
    this.changeId = info.legacyId();
    display(info);
    addHashtagIcon.setVisible(canEdit);
  }

  void onOpenForm() {
    UIObject.setVisible(form, true);
    UIObject.setVisible(error, false);
    addHashtagIcon.setVisible(false);
    hashtagTextBox.setFocus(true);
  }

  private void display(ChangeInfo info) {
    hashtagsText.setInnerSafeHtml(formatHashtags(info));
  }

  private void display(JsArrayString hashtags) {
    hashtagsText.setInnerSafeHtml(formatHashtags(hashtags));
  }

  private SafeHtmlBuilder formatHashtags(ChangeInfo info) {
    if (info.hashtags() != null) {
      return formatHashtags(info.hashtags());
    }
    return new SafeHtmlBuilder();
  }

  private SafeHtmlBuilder formatHashtags(JsArrayString hashtags) {
    SafeHtmlBuilder html = new SafeHtmlBuilder();
    Iterator<String> itr = Natives.asList(hashtags).iterator();
    while (itr.hasNext()) {
      String hashtagName = itr.next();
      html.openSpan()
          .setAttribute(DATA_ID, hashtagName)
          .setStyleName(style.hashtagName())
          .openAnchor()
          .setAttribute("href", "#" + PageLinks.toChangeQuery("hashtag:\"" + hashtagName + "\""))
          .setAttribute("role", "listitem")
          .openSpan()
          .setStyleName(style.hashtagIcon())
          .append(new ImageResourceRenderer().render(Gerrit.RESOURCES.hashtag()))
          .closeSpan()
          .append(" ")
          .append(hashtagName)
          .closeAnchor();
      if (canEdit) {
        html.openElement("button")
            .setAttribute("title", "Remove hashtag")
            .setAttribute("onclick", REMOVE + "(event)")
            .append("×")
            .closeElement("button");
      }
      html.closeSpan();
      if (itr.hasNext()) {
        html.append(' ');
      }
    }
    return html;
  }

  @UiHandler("cancel")
  void onCancel(@SuppressWarnings("unused") ClickEvent e) {
    addHashtagIcon.setVisible(true);
    UIObject.setVisible(form, false);
    hashtagTextBox.setFocus(false);
  }

  @UiHandler("add")
  void onAdd(@SuppressWarnings("unused") ClickEvent e) {
    String hashtag = hashtagTextBox.getText();
    if (!hashtag.isEmpty()) {
      addHashtag(hashtag);
    }
  }

  private void addHashtag(final String hashtags) {
    ChangeApi.hashtags(changeId.get())
        .post(
            PostInput.create(hashtags, null),
            new GerritCallback<JsArrayString>() {
              @Override
              public void onSuccess(JsArrayString result) {
                Gerrit.display(PageLinks.toChange(psId.getParentKey(), String.valueOf(psId.get())));
              }

              @Override
              public void onFailure(Throwable err) {
                UIObject.setVisible(error, true);
                error.setInnerText(
                    err instanceof StatusCodeException
                        ? ((StatusCodeException) err).getEncodedResponse()
                        : err.getMessage());
                hashtagTextBox.setEnabled(true);
              }
            });
  }

  public static class PostInput extends JavaScriptObject {
    public static PostInput create(String add, String remove) {
      PostInput input = createObject().cast();
      input.init(toJsArrayString(add), toJsArrayString(remove));
      return input;
    }

    private static JsArrayString toJsArrayString(String commaSeparated) {
      if (commaSeparated == null || commaSeparated.equals("")) {
        return null;
      }
      JsArrayString array = JsArrayString.createArray().cast();
      for (String hashtag : commaSeparated.split(",")) {
        array.push(hashtag.trim());
      }
      return array;
    }

    private native void init(JsArrayString add, JsArrayString remove) /*-{
      this.add = add;
      this.remove = remove;
    }-*/;

    protected PostInput() {}
  }
}
