// 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.core.client.Scheduler.ScheduledCommand;
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 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;

import java.util.List;

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 base;
  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(PatchSet.Id base, Patch.Key patch, int startLine) {
    this.base = base;
    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)
        .base(base)
        .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 new Runnable() {
      @Override
      public void run() {
        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(new Runnable() {
      @Override
      public void run() {
        cmBase.setOption("theme", newTheme.name().toLowerCase());
      }
    });
    cmEdit.operation(new Runnable() {
      @Override
      public void run() {
        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(new Runnable() {
      @Override
      public void run() {
        cmBase.setOption("showTrailingSpace", show);
      }
    });
    cmEdit.operation(new Runnable() {
      @Override
      public void run() {
        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", base, 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", base, new Patch.Key(revision, path)));
    unified.setTitle(PatchUtil.C.unifiedDiff());
    linkPanel.add(unified);
  }

  private Runnable updateCursorPosition() {
    return new Runnable() {
      @Override
      public void run() {
        // 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(new ScheduledCommand() {
          @Override
          public void execute() {
            cmEdit.operation(new Runnable() {
              @Override
              public void run() {
                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 new Runnable() {
      @Override
      public void run() {
        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()
        : "");
  }
}
