// 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.editor;

import static com.google.gwt.dom.client.Style.Visibility.HIDDEN;
import static com.google.gwt.dom.client.Style.Visibility.VISIBLE;

import com.google.gerrit.client.DiffWebLinkInfo;
import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.JumpKeys;
import com.google.gerrit.client.VoidResult;
import com.google.gerrit.client.account.EditPreferences;
import com.google.gerrit.client.changes.ChangeApi;
import com.google.gerrit.client.changes.ChangeEditApi;
import com.google.gerrit.client.diff.DiffApi;
import com.google.gerrit.client.diff.DiffInfo;
import com.google.gerrit.client.diff.Header;
import com.google.gerrit.client.info.ChangeInfo;
import com.google.gerrit.client.info.FileInfo;
import com.google.gerrit.client.patches.PatchUtil;
import com.google.gerrit.client.rpc.CallbackGroup;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.HttpCallback;
import com.google.gerrit.client.rpc.HttpResponse;
import com.google.gerrit.client.rpc.NativeString;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.client.ui.Screen;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.extensions.client.KeyMapType;
import com.google.gerrit.extensions.client.Theme;
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.Scheduler;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.shared.HandlerRegistration;
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.Window;
import com.google.gwt.user.client.Window.ClosingEvent;
import com.google.gwt.user.client.Window.ClosingHandler;
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.FlowPanel;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.ImageResourceRenderer;
import com.google.gwtexpui.globalkey.client.GlobalKey;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import java.util.List;
import net.codemirror.addon.AddonInjector;
import net.codemirror.addon.Addons;
import net.codemirror.lib.CodeMirror;
import net.codemirror.lib.CodeMirror.ChangesHandler;
import net.codemirror.lib.CodeMirror.CommandRunner;
import net.codemirror.lib.Configuration;
import net.codemirror.lib.KeyMap;
import net.codemirror.lib.MergeView;
import net.codemirror.lib.Pos;
import net.codemirror.mode.ModeInfo;
import net.codemirror.mode.ModeInjector;
import net.codemirror.theme.ThemeLoader;

public class EditScreen extends Screen {
  interface Binder extends UiBinder<HTMLPanel, EditScreen> {}

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

  interface Style extends CssResource {
    String fullWidth();

    String base();

    String hideBase();
  }

  private final PatchSet.Id revision;
  private final String path;
  private final int startLine;
  private EditPreferences prefs;
  private EditPreferencesAction editPrefsAction;
  private MergeView mv;
  private CodeMirror cmBase;
  private CodeMirror cmEdit;
  private HttpResponse<NativeString> content;
  private HttpResponse<NativeString> baseContent;
  private EditFileInfo editFileInfo;
  private JsArray<DiffWebLinkInfo> diffLinks;

  @UiField Element header;
  @UiField Element project;
  @UiField Element filePath;
  @UiField FlowPanel linkPanel;
  @UiField Element cursLine;
  @UiField Element cursCol;
  @UiField Element dirty;
  @UiField CheckBox showBase;
  @UiField Button close;
  @UiField Button save;
  @UiField Element editor;
  @UiField Style style;

  private HandlerRegistration resizeHandler;
  private HandlerRegistration closeHandler;
  private int generation;

  public EditScreen(Patch.Key patch, int startLine) {
    this.revision = patch.getParentKey();
    this.path = patch.get();
    this.startLine = startLine - 1;
    setRequiresSignIn(true);
    add(uiBinder.createAndBindUi(this));
    addDomHandler(GlobalKey.STOP_PROPAGATION, KeyPressEvent.getType());
  }

  @Override
  protected void onInitUI() {
    super.onInitUI();
    setHeaderVisible(false);
    setWindowTitle(FileInfo.getFileName(path));
  }

  @Override
  protected void onLoad() {
    super.onLoad();

    prefs = EditPreferences.create(Gerrit.getEditPreferences());

    CallbackGroup group1 = new CallbackGroup();
    final CallbackGroup group2 = new CallbackGroup();
    final CallbackGroup group3 = new CallbackGroup();

    CodeMirror.initLibrary(
        group1.add(
            new AsyncCallback<Void>() {
              final AsyncCallback<Void> themeCallback = group3.addEmpty();

              @Override
              public void onSuccess(Void result) {
                // Load theme after CM library to ensure theme can override CSS.
                ThemeLoader.loadTheme(prefs.theme(), themeCallback);
                group2.done();

                new AddonInjector()
                    .add(Addons.I.merge_bundled().getName())
                    .inject(
                        new AsyncCallback<Void>() {
                          @Override
                          public void onFailure(Throwable caught) {}

                          @Override
                          public void onSuccess(Void result) {
                            if (!prefs.showBase() || revision.get() > 0) {
                              group3.done();
                            }
                          }
                        });
              }

              @Override
              public void onFailure(Throwable caught) {}
            }));

    ChangeApi.detail(
        revision.getParentKey().get(),
        group1.add(
            new AsyncCallback<ChangeInfo>() {
              @Override
              public void onSuccess(ChangeInfo c) {
                project.setInnerText(c.project());
                SafeHtml.setInnerHTML(filePath, Header.formatPath(path));
              }

              @Override
              public void onFailure(Throwable caught) {}
            }));

    if (revision.get() == 0) {
      ChangeEditApi.getMeta(
          revision,
          path,
          group1.add(
              new AsyncCallback<EditFileInfo>() {
                @Override
                public void onSuccess(EditFileInfo editInfo) {
                  editFileInfo = editInfo;
                }

                @Override
                public void onFailure(Throwable e) {}
              }));

      if (prefs.showBase()) {
        ChangeEditApi.get(
            revision,
            path,
            true /* base */,
            group1.addFinal(
                new HttpCallback<NativeString>() {
                  @Override
                  public void onSuccess(HttpResponse<NativeString> fc) {
                    baseContent = fc;
                    group3.done();
                  }

                  @Override
                  public void onFailure(Throwable e) {}
                }));
      } else {
        group1.done();
      }
    } else {
      // TODO(davido): We probably want to create dedicated GET EditScreenMeta
      // REST endpoint. Abuse GET diff for now, as it retrieves links we need.
      DiffApi.diff(revision, path)
          .webLinksOnly()
          .get(
              group1.addFinal(
                  new AsyncCallback<DiffInfo>() {
                    @Override
                    public void onSuccess(DiffInfo diffInfo) {
                      diffLinks = diffInfo.webLinks();
                    }

                    @Override
                    public void onFailure(Throwable e) {}
                  }));
    }

    ChangeEditApi.get(
        revision,
        path,
        group2.add(
            new HttpCallback<NativeString>() {
              final AsyncCallback<Void> modeCallback = group3.addEmpty();

              @Override
              public void onSuccess(HttpResponse<NativeString> fc) {
                content = fc;
                if (revision.get() > 0) {
                  baseContent = fc;
                }

                if (prefs.syntaxHighlighting()) {
                  injectMode(fc.getContentType(), modeCallback);
                } else {
                  modeCallback.onSuccess(null);
                }
              }

              @Override
              public void onFailure(Throwable e) {
                // "Not Found" means it's a new file.
                if (RestApi.isNotFound(e)) {
                  content = null;
                  modeCallback.onSuccess(null);
                } else {
                  GerritCallback.showFailure(e);
                }
              }
            }));

    group3.addListener(
        new ScreenLoadCallback<Void>(this) {
          @Override
          protected void preDisplay(Void result) {
            initEditor();

            renderLinks(editFileInfo, diffLinks);
            editFileInfo = null;
            diffLinks = null;

            showBase.setValue(prefs.showBase(), true);
            cmBase.refresh();
          }
        });
  }

  @Override
  public void registerKeys() {
    super.registerKeys();
    KeyMap localKeyMap = KeyMap.create();
    localKeyMap.on("Ctrl-L", gotoLine()).on("Cmd-L", gotoLine()).on("Cmd-S", save());

    // TODO(davido): Find a better way to prevent key maps collisions
    if (prefs.keyMapType() != KeyMapType.EMACS) {
      localKeyMap.on("Ctrl-S", save());
    }

    cmBase.addKeyMap(localKeyMap);
    cmEdit.addKeyMap(localKeyMap);
  }

  private Runnable gotoLine() {
    return () -> {
      cmEdit.execCommand("jumpToLine");
    };
  }

  @Override
  public void onShowView() {
    super.onShowView();
    Window.enableScrolling(false);
    JumpKeys.enable(false);
    if (prefs.hideTopMenu()) {
      Gerrit.setHeaderVisible(false);
    }
    resizeHandler =
        Window.addResizeHandler(
            new ResizeHandler() {
              @Override
              public void onResize(ResizeEvent event) {
                adjustHeight();
              }
            });
    closeHandler =
        Window.addWindowClosingHandler(
            new ClosingHandler() {
              @Override
              public void onWindowClosing(ClosingEvent event) {
                if (!cmEdit.isClean(generation)) {
                  event.setMessage(EditConstants.I.closeUnsavedChanges());
                }
              }
            });

    generation = cmEdit.changeGeneration(true);
    setClean(true);
    cmEdit.on(
        new ChangesHandler() {
          @Override
          public void handle(CodeMirror cm) {
            setClean(cm.isClean(generation));
          }
        });

    adjustHeight();
    cmEdit.on("cursorActivity", updateCursorPosition());
    setShowTabs(prefs.showTabs());
    setLineLength(prefs.lineLength());
    cmEdit.refresh();
    cmEdit.focus();

    if (startLine > 0) {
      cmEdit.scrollToLine(startLine);
    }
    updateActiveLine();
    editPrefsAction = new EditPreferencesAction(this, prefs);
  }

  @Override
  protected void onUnload() {
    super.onUnload();
    if (cmBase != null) {
      cmBase.getWrapperElement().removeFromParent();
    }
    if (cmEdit != null) {
      cmEdit.getWrapperElement().removeFromParent();
    }
    if (resizeHandler != null) {
      resizeHandler.removeHandler();
    }
    if (closeHandler != null) {
      closeHandler.removeHandler();
    }
    Window.enableScrolling(true);
    Gerrit.setHeaderVisible(true);
    JumpKeys.enable(true);
  }

  CodeMirror getEditor() {
    return cmEdit;
  }

  @UiHandler("editSettings")
  void onEditSetting(@SuppressWarnings("unused") ClickEvent e) {
    editPrefsAction.show();
  }

  @UiHandler("save")
  void onSave(@SuppressWarnings("unused") ClickEvent e) {
    save().run();
  }

  @UiHandler("close")
  void onClose(@SuppressWarnings("unused") ClickEvent e) {
    if (cmEdit.isClean(generation) || Window.confirm(EditConstants.I.cancelUnsavedChanges())) {
      upToChange();
    }
  }

  private void displayBase() {
    cmBase.getWrapperElement().getParentElement().removeClassName(style.hideBase());
    cmEdit.getWrapperElement().getParentElement().removeClassName(style.fullWidth());
    mv.getGapElement().removeClassName(style.hideBase());
    setCmBaseValue();
    setLineLength(prefs.lineLength());
    cmBase.refresh();
  }

  @UiHandler("showBase")
  void onShowBase(ValueChangeEvent<Boolean> e) {
    boolean shouldShow = e.getValue();
    if (shouldShow) {
      if (baseContent == null) {
        ChangeEditApi.get(
            revision,
            path,
            true /* base */,
            new HttpCallback<NativeString>() {
              @Override
              public void onSuccess(HttpResponse<NativeString> fc) {
                baseContent = fc;
                displayBase();
              }

              @Override
              public void onFailure(Throwable e) {}
            });
      } else {
        displayBase();
      }
    } else {
      cmBase.getWrapperElement().getParentElement().addClassName(style.hideBase());
      cmEdit.getWrapperElement().getParentElement().addClassName(style.fullWidth());
      mv.getGapElement().addClassName(style.hideBase());
    }
    mv.setShowDifferences(shouldShow);
  }

  void setOption(String option, String value) {
    cmBase.setOption(option, value);
    cmEdit.setOption(option, value);
  }

  void setOption(String option, boolean value) {
    cmBase.setOption(option, value);
    cmEdit.setOption(option, value);
  }

  void setOption(String option, double value) {
    cmBase.setOption(option, value);
    cmEdit.setOption(option, value);
  }

  void setTheme(final Theme newTheme) {
    cmBase.operation(
        () -> {
          cmBase.setOption("theme", newTheme.name().toLowerCase());
        });
    cmEdit.operation(
        () -> {
          cmEdit.setOption("theme", newTheme.name().toLowerCase());
        });
  }

  void setLineLength(int length) {
    int adjustedLength = Patch.COMMIT_MSG.equals(path) ? 72 : length;
    cmBase.extras().lineLength(adjustedLength);
    cmEdit.extras().lineLength(adjustedLength);
  }

  void setIndentUnit(int indent) {
    cmEdit.setOption("indentUnit", Patch.COMMIT_MSG.equals(path) ? 2 : indent);
  }

  void setShowLineNumbers(boolean show) {
    cmBase.setOption("lineNumbers", show);
    cmEdit.setOption("lineNumbers", show);
  }

  void setShowWhitespaceErrors(final boolean show) {
    cmBase.operation(
        () -> {
          cmBase.setOption("showTrailingSpace", show);
        });
    cmEdit.operation(
        () -> {
          cmEdit.setOption("showTrailingSpace", show);
        });
  }

  void setShowTabs(boolean show) {
    cmBase.extras().showTabs(show);
    cmEdit.extras().showTabs(show);
  }

  void adjustHeight() {
    int height = header.getOffsetHeight();
    int rest = Gerrit.getHeaderFooterHeight() + height + 5; // Estimate
    mv.getGapElement().getStyle().setHeight(Window.getClientHeight() - rest, Unit.PX);
    cmBase.adjustHeight(height);
    cmEdit.adjustHeight(height);
  }

  void setSyntaxHighlighting(boolean b) {
    ModeInfo modeInfo = ModeInfo.findMode(content.getContentType(), path);
    final String mode = modeInfo != null ? modeInfo.mime() : null;
    if (b && mode != null && !mode.isEmpty()) {
      injectMode(
          mode,
          new AsyncCallback<Void>() {
            @Override
            public void onSuccess(Void result) {
              cmBase.setOption("mode", mode);
              cmEdit.setOption("mode", mode);
            }

            @Override
            public void onFailure(Throwable caught) {
              prefs.syntaxHighlighting(false);
            }
          });
    } else {
      cmBase.setOption("mode", (String) null);
      cmEdit.setOption("mode", (String) null);
    }
  }

  private void upToChange() {
    Gerrit.display(PageLinks.toChangeInEditMode(revision.getParentKey()));
  }

  private void initEditor() {
    ModeInfo mode = null;
    String editContent = "";
    if (content != null && content.getResult() != null) {
      editContent = content.getResult().asString();
      if (prefs.syntaxHighlighting()) {
        mode = ModeInfo.findMode(content.getContentType(), path);
      }
    }
    mv =
        MergeView.create(
            editor,
            Configuration.create()
                .set("autoCloseBrackets", prefs.autoCloseBrackets())
                .set("cursorBlinkRate", prefs.cursorBlinkRate())
                .set("cursorHeight", 0.85)
                .set("indentUnit", prefs.indentUnit())
                .set("keyMap", prefs.keyMapType().name().toLowerCase())
                .set("lineNumbers", prefs.hideLineNumbers())
                .set("lineWrapping", false)
                .set("matchBrackets", prefs.matchBrackets())
                .set("mode", mode != null ? mode.mime() : null)
                .set("origLeft", editContent)
                .set("scrollbarStyle", "overlay")
                .set("showTrailingSpace", prefs.showWhitespaceErrors())
                .set("styleSelectedText", true)
                .set("tabSize", prefs.tabSize())
                .set("theme", prefs.theme().name().toLowerCase())
                .set("value", ""));

    cmBase = mv.leftOriginal();
    cmBase.getWrapperElement().addClassName(style.base());
    cmEdit = mv.editor();
    setCmBaseValue();
    cmEdit.setValue(editContent);

    CodeMirror.addCommand(
        "save",
        new CommandRunner() {
          @Override
          public void run(CodeMirror instance) {
            save().run();
          }
        });
  }

  private void renderLinks(EditFileInfo editInfo, JsArray<DiffWebLinkInfo> diffLinks) {
    renderLinksToDiff();

    if (editInfo != null) {
      renderLinks(Natives.asList(editInfo.webLinks()));
    } else if (diffLinks != null) {
      renderLinks(Natives.asList(diffLinks));
    }
  }

  private void renderLinks(List<DiffWebLinkInfo> links) {
    if (links != null) {
      for (DiffWebLinkInfo webLink : links) {
        linkPanel.add(webLink.toAnchor());
      }
    }
  }

  private void renderLinksToDiff() {
    InlineHyperlink sbs = new InlineHyperlink();
    sbs.setHTML(new ImageResourceRenderer().render(Gerrit.RESOURCES.sideBySideDiff()));
    sbs.setTargetHistoryToken(
        Dispatcher.toPatch("sidebyside", null, new Patch.Key(revision, path)));
    sbs.setTitle(PatchUtil.C.sideBySideDiff());
    linkPanel.add(sbs);

    InlineHyperlink unified = new InlineHyperlink();
    unified.setHTML(new ImageResourceRenderer().render(Gerrit.RESOURCES.unifiedDiff()));
    unified.setTargetHistoryToken(
        Dispatcher.toPatch("unified", null, new Patch.Key(revision, path)));
    unified.setTitle(PatchUtil.C.unifiedDiff());
    linkPanel.add(unified);
  }

  private Runnable updateCursorPosition() {
    return () -> {
      // The rendering of active lines has to be deferred. Reflow
      // caused by adding and removing styles chokes Firefox when arrow
      // key (or j/k) is held down. Performance on Chrome is fine
      // without the deferral.
      //
      Scheduler.get()
          .scheduleDeferred(
              () -> {
                cmEdit.operation(this::updateActiveLine);
              });
    };
  }

  private void updateActiveLine() {
    Pos p = cmEdit.getCursor("end");
    cursLine.setInnerText(Integer.toString(p.line() + 1));
    cursCol.setInnerText(Integer.toString(p.ch() + 1));
    cmEdit.extras().activeLine(cmEdit.getLineHandleVisualStart(p.line()));
  }

  private void setClean(boolean clean) {
    save.setEnabled(!clean);
    close.setEnabled(true);
    dirty.getStyle().setVisibility(!clean ? VISIBLE : HIDDEN);
  }

  private Runnable save() {
    return () -> {
      if (!cmEdit.isClean(generation)) {
        close.setEnabled(false);
        String text = cmEdit.getValue();
        if (Patch.COMMIT_MSG.equals(path)) {
          String trimmed = text.trim() + "\r";
          if (!trimmed.equals(text)) {
            text = trimmed;
            cmEdit.setValue(text);
          }
        }
        final int g = cmEdit.changeGeneration(false);
        ChangeEditApi.put(
            revision.getParentKey().get(),
            path,
            text,
            new GerritCallback<VoidResult>() {
              @Override
              public void onSuccess(VoidResult result) {
                generation = g;
                setClean(cmEdit.isClean(g));
              }

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

  private void injectMode(String type, AsyncCallback<Void> cb) {
    new ModeInjector().add(type).inject(cb);
  }

  private void setCmBaseValue() {
    cmBase.setValue(
        baseContent != null && baseContent.getResult() != null
            ? baseContent.getResult().asString()
            : "");
  }
}
