// 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.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.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.shared.HandlerRegistration;
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.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.lib.CodeMirror;
import net.codemirror.lib.CodeMirror.ChangesHandler;
import net.codemirror.lib.Configuration;
import net.codemirror.lib.KeyMap;
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);

  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 CodeMirror cm;
  private HttpResponse<NativeString> content;
  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 Button close;
  @UiField Button save;
  @UiField Element editor;

  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();
        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, null, null));
          }

          @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) {
            }
          }));
    } 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.add(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 (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(content);

        renderLinks(editFileInfo, diffLinks);
        editFileInfo = null;
        diffLinks = null;
      }
    });
    group1.done();
  }

  @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());
    }

    cm.addKeyMap(localKeyMap);
  }

  private Runnable gotoLine() {
    return new Runnable() {
      @Override
      public void run() {
        String n = Window.prompt(EditConstants.I.gotoLineNumber(), "");
        if (n != null) {
          try {
            int line = Integer.parseInt(n);
            line--;
            if (line >= 0) {
              cm.scrollToLine(line);
            }
          } catch (NumberFormatException e) {
            // ignore non valid numbers
            // We don't want to popup another ugly dialog just to say
            // "The number you've provided is invalid, try again"
          }
        }
      }
    };
  }

  @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) {
        cm.adjustHeight(header.getOffsetHeight());
      }
    });
    closeHandler = Window.addWindowClosingHandler(new ClosingHandler() {
      @Override
      public void onWindowClosing(ClosingEvent event) {
        if (!cm.isClean(generation)) {
          event.setMessage(EditConstants.I.closeUnsavedChanges());
        }
      }
    });

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

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

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

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

  CodeMirror getEditor() {
    return cm;
  }

  @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 (cm.isClean(generation)
        || Window.confirm(EditConstants.I.cancelUnsavedChanges())) {
      upToChange();
    }
  }

  void setLineLength(int length) {
    cm.extras().lineLength(
        Patch.COMMIT_MSG.equals(path) ? 72 : length);
  }

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

  void setShowWhitespaceErrors(final boolean show) {
    cm.operation(new Runnable() {
      @Override
      public void run() {
        cm.setOption("showTrailingSpace", show);
      }
    });
  }

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

  void resizeCodeMirror() {
    cm.adjustHeight(header.getOffsetHeight());
  }

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

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

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

  private void initEditor(HttpResponse<NativeString> file) {
    ModeInfo mode = null;
    String content = "";
    if (file != null && file.getResult() != null) {
      content = file.getResult().asString();
      if (prefs.syntaxHighlighting()) {
        mode = ModeInfo.findMode(file.getContentType(), path);
      }
    }
    cm = CodeMirror.create(editor, Configuration.create()
        .set("value", content)
        .set("readOnly", false)
        .set("cursorBlinkRate", prefs.cursorBlinkRate())
        .set("cursorHeight", 0.85)
        .set("lineNumbers", prefs.hideLineNumbers())
        .set("tabSize", prefs.tabSize())
        .set("lineWrapping", false)
        .set("matchBrackets", prefs.matchBrackets())
        .set("autoCloseBrackets", prefs.autoCloseBrackets())
        .set("scrollbarStyle", "overlay")
        .set("styleSelectedText", true)
        .set("showTrailingSpace", prefs.showWhitespaceErrors())
        .set("keyMap", prefs.keyMapType().name().toLowerCase())
        .set("theme", prefs.theme().name().toLowerCase())
        .set("mode", mode != null ? mode.mode() : null));
  }

  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() {
            cm.operation(new Runnable() {
              @Override
              public void run() {
                updateActiveLine();
              }
            });
          }
        });
      }
    };
  }

  private void updateActiveLine() {
    Pos p = cm.getCursor("end");
    cursLine.setInnerText(Integer.toString(p.line() + 1));
    cursCol.setInnerText(Integer.toString(p.ch() + 1));
    cm.extras().activeLine(cm.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 (!cm.isClean(generation)) {
          close.setEnabled(false);
          String text = cm.getValue();
          if (Patch.COMMIT_MSG.equals(path)) {
            String trimmed = text.trim() + "\r";
            if (!trimmed.equals(text)) {
              text = trimmed;
              cm.setValue(text);
            }
          }
          final int g = cm.changeGeneration(false);
          ChangeEditApi.put(revision.getParentKey().get(), path, text,
              new GerritCallback<VoidResult>() {
                @Override
                public void onSuccess(VoidResult result) {
                  generation = g;
                  setClean(cm.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);
  }
}
