// 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.googlesource.gerrit.plugins.xdocs.client;

import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.plugin.client.Plugin;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.InlineHTML;
import com.google.gwt.user.client.ui.InlineHyperlink;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;

import com.googlesource.gerrit.plugins.xdocs.client.ChangeInfo.EditInfo;
import com.googlesource.gerrit.plugins.xdocs.client.ChangeInfo.RevisionInfo;

import java.util.List;

public abstract class XDocDiffScreen extends VerticalPanel {
  protected final String changeId;
  protected final String path;
  protected String revisionA;
  protected String revisionB;
  protected int patchSet;
  protected Integer base;
  private FlowPanel iconPanel;
  private FlowPanel additionalIconPanel;

  XDocDiffScreen(String changeId, final String patchSet, String path) {
    setStyleName("xdocs-panel");

    this.changeId = changeId;
    this.path = path;

    ChangeApi.getChangeInfo(changeId, new AsyncCallback<ChangeInfo>() {

      @Override
      public void onSuccess(final ChangeInfo change) {
        change.revisions().copyKeysIntoChildren("name");
        if (Plugin.get().isSignedIn()) {
          ChangeApi.edit(change._number(), new AsyncCallback<EditInfo>() {
            @Override
            public void onSuccess(EditInfo edit) {
              if (edit != null) {
                change.set_edit(edit);
                change.revisions().put(edit.name(), RevisionInfo.fromEdit(edit));
              }
              initRevisionsAndShow(change);
            }

            @Override
            public void onFailure(Throwable caught) {
              // never invoked
            }
          });
        } else {
          initRevisionsAndShow(change);
        }
      }

      private void initRevisionsAndShow(final ChangeInfo change) {
        parseRevisions(change, patchSet);
        if (revisionA == null) {
          ProjectApi.getCommitInfo(change.project(), change.current_revision(),
              new AsyncCallback<CommitInfo>() {
                @Override
                public void onSuccess(CommitInfo commit) {
                  if (commit.parents() != null) {
                    List<CommitInfo> parents = Natives.asList(commit.parents());
                    if (!parents.isEmpty()) {
                      revisionA = parents.get(0).commit();
                    }
                  }
                  show(change);
                }

                @Override
                public void onFailure(Throwable caught) {
                  // never invoked
                }
              });
        } else {
          show(change);
        }
      }

      private void show(ChangeInfo change) {
        addHeader(change);
        init();
        display(change);
      }

      @Override
      public void onFailure(Throwable caught) {
        showError("Unable to load change " + XDocDiffScreen.this.changeId
            + ": " + caught.getMessage());
      }
    });
  }

  protected abstract void display(ChangeInfo change);

  protected String getPath() {
    return path;
  }

  protected String getRevisionA() {
    return revisionA;
  }

  protected String getRevisionB() {
    return revisionB;
  }

  private void parseRevisions(ChangeInfo change, String patchSetString) {
    int i = patchSetString.indexOf("..");
    if (i > 0) {
      base = parsePatchSet(patchSetString.substring(0, i));
      revisionA = getRevision(change, base);
      if (patchSetString.length() > i + 2) {
        patchSet = parsePatchSet(patchSetString.substring(i + 2));
        revisionB = getRevision(change, patchSet);
      } else {
        throw new IllegalArgumentException("Invalid patch set: " + patchSetString);
      }
    } else {
      patchSet = parsePatchSet(patchSetString);
      revisionB = getRevision(change, patchSet);
    }
  }

  private static String getRevision(ChangeInfo change, int patchSet) {
    for (RevisionInfo rev : Natives.asList(change.revisions().values())) {
      if (rev.is_edit()) {
        return rev.commit().commit();
      }
      if (rev._number() == patchSet) {
        return rev.ref();
      }
    }
    throw new IllegalArgumentException("Patch set " + patchSet + " not found.");
  }

  private static int parsePatchSet(String patchSet) {
    try {
      return Integer.valueOf(patchSet);
    } catch (NumberFormatException e) {
      throw new IllegalArgumentException("Invalid patch set: " + patchSet);
    }
  }

  private void addHeader(ChangeInfo change) {
    HorizontalPanel p = new HorizontalPanel();
    p.setStyleName("xdocs-header");
    p.add(getPathHeader(change));

    iconPanel = new FlowPanel();
    iconPanel.setStyleName("xdocs-icon-panel");
    p.add(iconPanel);
    additionalIconPanel = new FlowPanel();
    iconPanel.add(additionalIconPanel);
    addNavigationButtons(change);

    add(p);
  }

  protected void init() {
  }

  private Widget getPathHeader(ChangeInfo change) {
    HorizontalPanel p = new HorizontalPanel();
    p.setStyleName("xdocs-file-header");
    p.add(new InlineHyperlink(change.project(), "/admin/projects/" + change.project()));
    p.add(new Label("/"));

    SafeHtmlBuilder html = new SafeHtmlBuilder();
    if (FileInfo.COMMIT_MSG.equals(path)) {
      html.append("Commit Message");
    } else {
      int s = path.lastIndexOf('/') + 1;
      html.append(path.substring(0, s));
      html.openElement("b");
      html.append(path.substring(s));
      html.closeElement("b");
    }
    p.add(new InlineHTML(html.toSafeHtml()));

    return p;
  }

  private void addNavigationButtons(final ChangeInfo change) {
    DiffApi.list(changeId, patchSet, base,
        new AsyncCallback<NativeMap<FileInfo>>() {
      @Override
      public void onSuccess(NativeMap<FileInfo> result) {
        JsArray<FileInfo> files = result.values();
        FileInfo.sortFileInfoByPath(files);
        int index = 0;
        for (int i = 0; i < files.length(); i++) {
          if (path.equals(files.get(i).path())) {
            index = i;
            break;
          }
        }

        FileInfo prevInfo = index == 0 ? null : files.get(index - 1);
        if (prevInfo != null) {
          iconPanel.add(createNavLink(XDocsPlugin.RESOURCES.goPrev(),
              change, patchSet, base, prevInfo));
        }

        iconPanel.add(createIcon(XDocsPlugin.RESOURCES.goUp(),
            "Up to change", toChange(change)));

        FileInfo nextInfo = index == files.length() - 1
            ? null
            : files.get(index + 1);
        if (nextInfo != null) {
          iconPanel.add(createNavLink(XDocsPlugin.RESOURCES.goNext(),
              change, patchSet, base, nextInfo));
        }
      }

      @Override
      public void onFailure(Throwable caught) {
        showError("Unable to load files of change " + changeId + ": "
            + caught.getMessage());
      }
    });
  }

  private InlineHyperlink createNavLink(ImageResource res,
      final ChangeInfo change, final int patchSet, final Integer base,
      final FileInfo file) {
    final InlineHyperlink link = createIcon(
        res, FileInfo.getFileName(file.path()),
        toFile(change, patchSet, base, file));
    XDocApi.checkHtml(XDocApi.getUrl(change.project(),
        getRevision(change, patchSet), file.path()),
        new AsyncCallback<VoidResult>() {
      @Override
      public void onSuccess(VoidResult result) {
        link.setTargetHistoryToken(
            toPreview(change, patchSet, base, file));
      }

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

  protected static InlineHyperlink createIcon(ImageResource res, String tooltip, String target) {
    InlineHyperlink l = new InlineHyperlink(
        AbstractImagePrototype.create(res).getHTML(), true, target);
    if (tooltip != null) {
      l.setTitle(tooltip);
    }
    return l;
  }

  protected void addIcon(InlineHyperlink icon) {
    additionalIconPanel.add(icon);
  }

  private String toPreview(ChangeInfo change, int patchSet,
      Integer base, FileInfo file) {
    String panel = getPanel();
    return "/x/" + Plugin.get().getName()
        + toPatchSet(change, patchSet, base)
        + file.path()
        + (panel != null ? "," + panel : "");
  }

  private String toFile(ChangeInfo change, int patchSet, Integer base,
      FileInfo file) {
    String panel = file.binary() ? "unified" : getPanel();
    return toPatchSet(change, patchSet, base)
        + file.path()
        + (panel != null ? "," + panel : "");
  }

  protected String getPanel() {
    return null;
  }

  private static String toPatchSet(ChangeInfo change, int patchSet, Integer base) {
    return toChange(change)
        + (base != null ? patchSet + ".." + base : patchSet) + "/";
  }

  private static String toChange(ChangeInfo change) {
    return "/c/" + change._number() + "/";
  }

  protected void showError(String message) {
    Label l = new Label(message);
    l.setStyleName("xdocs-error");
    add(l);
  }

  protected static int addRow(FlexTable table) {
    int row = table.getRowCount();
    table.insertRow(row);
    return row;
  }
}
