// Copyright (C) 2008 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;

import static com.google.gerrit.common.PageLinks.ADMIN_CREATE_GROUP;
import static com.google.gerrit.common.PageLinks.ADMIN_CREATE_PROJECT;
import static com.google.gerrit.common.PageLinks.ADMIN_GROUPS;
import static com.google.gerrit.common.PageLinks.ADMIN_PLUGINS;
import static com.google.gerrit.common.PageLinks.ADMIN_PROJECTS;
import static com.google.gerrit.common.PageLinks.DASHBOARDS;
import static com.google.gerrit.common.PageLinks.MINE;
import static com.google.gerrit.common.PageLinks.MY_GROUPS;
import static com.google.gerrit.common.PageLinks.PROJECTS;
import static com.google.gerrit.common.PageLinks.QUERY;
import static com.google.gerrit.common.PageLinks.REGISTER;
import static com.google.gerrit.common.PageLinks.SETTINGS;
import static com.google.gerrit.common.PageLinks.SETTINGS_AGREEMENTS;
import static com.google.gerrit.common.PageLinks.SETTINGS_CONTACT;
import static com.google.gerrit.common.PageLinks.SETTINGS_DIFF_PREFERENCES;
import static com.google.gerrit.common.PageLinks.SETTINGS_EDIT_PREFERENCES;
import static com.google.gerrit.common.PageLinks.SETTINGS_EXTENSION;
import static com.google.gerrit.common.PageLinks.SETTINGS_GPGKEYS;
import static com.google.gerrit.common.PageLinks.SETTINGS_HTTP_PASSWORD;
import static com.google.gerrit.common.PageLinks.SETTINGS_MYGROUPS;
import static com.google.gerrit.common.PageLinks.SETTINGS_NEW_AGREEMENT;
import static com.google.gerrit.common.PageLinks.SETTINGS_OAUTH_TOKEN;
import static com.google.gerrit.common.PageLinks.SETTINGS_PREFERENCES;
import static com.google.gerrit.common.PageLinks.SETTINGS_PROJECTS;
import static com.google.gerrit.common.PageLinks.SETTINGS_SSHKEYS;
import static com.google.gerrit.common.PageLinks.SETTINGS_WEBIDENT;

import com.google.gerrit.client.account.MyAgreementsScreen;
import com.google.gerrit.client.account.MyContactInformationScreen;
import com.google.gerrit.client.account.MyDiffPreferencesScreen;
import com.google.gerrit.client.account.MyEditPreferencesScreen;
import com.google.gerrit.client.account.MyGpgKeysScreen;
import com.google.gerrit.client.account.MyGroupsScreen;
import com.google.gerrit.client.account.MyIdentitiesScreen;
import com.google.gerrit.client.account.MyOAuthTokenScreen;
import com.google.gerrit.client.account.MyPasswordScreen;
import com.google.gerrit.client.account.MyPreferencesScreen;
import com.google.gerrit.client.account.MyProfileScreen;
import com.google.gerrit.client.account.MySshKeysScreen;
import com.google.gerrit.client.account.MyWatchedProjectsScreen;
import com.google.gerrit.client.account.NewAgreementScreen;
import com.google.gerrit.client.account.RegisterScreen;
import com.google.gerrit.client.account.ValidateEmailScreen;
import com.google.gerrit.client.admin.AccountGroupAuditLogScreen;
import com.google.gerrit.client.admin.AccountGroupInfoScreen;
import com.google.gerrit.client.admin.AccountGroupMembersScreen;
import com.google.gerrit.client.admin.AccountGroupScreen;
import com.google.gerrit.client.admin.CreateGroupScreen;
import com.google.gerrit.client.admin.CreateProjectScreen;
import com.google.gerrit.client.admin.GroupListScreen;
import com.google.gerrit.client.admin.PluginListScreen;
import com.google.gerrit.client.admin.ProjectAccessScreen;
import com.google.gerrit.client.admin.ProjectBranchesScreen;
import com.google.gerrit.client.admin.ProjectDashboardsScreen;
import com.google.gerrit.client.admin.ProjectInfoScreen;
import com.google.gerrit.client.admin.ProjectListScreen;
import com.google.gerrit.client.admin.ProjectScreen;
import com.google.gerrit.client.admin.ProjectTagsScreen;
import com.google.gerrit.client.api.ExtensionScreen;
import com.google.gerrit.client.api.ExtensionSettingsScreen;
import com.google.gerrit.client.change.ChangeScreen;
import com.google.gerrit.client.change.FileTable;
import com.google.gerrit.client.change.ProjectChangeId;
import com.google.gerrit.client.changes.AccountDashboardScreen;
import com.google.gerrit.client.changes.CustomDashboardScreen;
import com.google.gerrit.client.changes.ProjectDashboardScreen;
import com.google.gerrit.client.changes.QueryScreen;
import com.google.gerrit.client.dashboards.DashboardInfo;
import com.google.gerrit.client.dashboards.DashboardList;
import com.google.gerrit.client.diff.DisplaySide;
import com.google.gerrit.client.diff.SideBySide;
import com.google.gerrit.client.diff.Unified;
import com.google.gerrit.client.documentation.DocScreen;
import com.google.gerrit.client.editor.EditScreen;
import com.google.gerrit.client.groups.GroupApi;
import com.google.gerrit.client.info.GroupInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.client.ui.Screen;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DiffView;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.http.client.URL;
import com.google.gwtexpui.user.client.UserAgent;
import com.google.gwtorm.client.KeyUtil;

public class Dispatcher {
  public static String toPatch(
      @Nullable Project.NameKey project,
      DiffObject diffBase,
      PatchSet.Id revision,
      String fileName) {
    return toPatch("", project, diffBase, revision, fileName, null, 0);
  }

  public static String toPatch(
      @Nullable Project.NameKey project,
      DiffObject diffBase,
      PatchSet.Id revision,
      String fileName,
      DisplaySide side,
      int line) {
    return toPatch("", project, diffBase, revision, fileName, side, line);
  }

  public static String toSideBySide(
      @Nullable Project.NameKey project,
      DiffObject diffBase,
      PatchSet.Id revision,
      String fileName) {
    return toPatch("sidebyside", project, diffBase, revision, fileName, null, 0);
  }

  public static String toUnified(
      @Nullable Project.NameKey project,
      DiffObject diffBase,
      PatchSet.Id revision,
      String fileName) {
    return toPatch("unified", project, diffBase, revision, fileName, null, 0);
  }

  public static String toPatch(
      @Nullable Project.NameKey project, String type, DiffObject diffBase, Patch.Key id) {
    return toPatch(type, project, diffBase, id.getParentKey(), id.get(), null, 0);
  }

  public static String toEditScreen(
      @Nullable Project.NameKey project, PatchSet.Id revision, String fileName) {
    return toEditScreen(project, revision, fileName, 0);
  }

  public static String toEditScreen(
      @Nullable Project.NameKey project, PatchSet.Id revision, String fileName, int line) {
    return toPatch("edit", project, DiffObject.base(), revision, fileName, null, line);
  }

  private static String toPatch(
      String type,
      @Nullable Project.NameKey project,
      DiffObject diffBase,
      PatchSet.Id revision,
      String fileName,
      DisplaySide side,
      int line) {
    Change.Id c = revision.getParentKey();
    StringBuilder p = new StringBuilder(PageLinks.toChange(project, c));
    if (diffBase != null && diffBase.asString() != null) {
      p.append(diffBase.asString()).append("..");
    }
    p.append(revision.getId()).append("/").append(KeyUtil.encode(fileName));
    if (type != null && !type.isEmpty() && (!"sidebyside".equals(type) || preferUnified())) {
      p.append(",").append(type);
    }
    if (side == DisplaySide.A && line > 0) {
      p.append("@a").append(line);
    } else if (line > 0) {
      p.append("@").append(line);
    }
    return p.toString();
  }

  public static String toGroup(AccountGroup.Id id) {
    return ADMIN_GROUPS + id.toString();
  }

  public static String toGroup(AccountGroup.Id id, String panel) {
    return ADMIN_GROUPS + id.toString() + "," + panel;
  }

  public static String toGroup(AccountGroup.UUID uuid) {
    return PageLinks.toGroup(uuid);
  }

  public static String toGroup(AccountGroup.UUID uuid, String panel) {
    return toGroup(uuid) + "," + panel;
  }

  public static String toProject(Project.NameKey n) {
    return toProjectAdmin(n, ProjectScreen.getSavedPanel());
  }

  public static String toProjectAdmin(Project.NameKey n, String panel) {
    if (panel == null || ProjectScreen.INFO.equals(panel)) {
      return ADMIN_PROJECTS + n.toString();
    }
    return ADMIN_PROJECTS + n.toString() + "," + panel;
  }

  static final String RELOAD_UI = "/reload-ui/";
  private static boolean wasStartedByReloadUI;

  void display(String token) {
    assert token != null;
    try {
      try {
        if (matchPrefix(RELOAD_UI, token)) {
          wasStartedByReloadUI = true;
          token = skip(token);
        }
        select(token);
      } finally {
        wasStartedByReloadUI = false;
      }
    } catch (RuntimeException err) {
      GWT.log("Error parsing history token: " + token, err);
      Gerrit.display(token, new NotFoundScreen());
    }
  }

  private static void select(String token) {
    token = Gerrit.getUrlAliasMatcher().replace(token);

    if (matchPrefix(QUERY, token)) {
      query(token);

    } else if (matchPrefix("/Documentation/", token)) {
      docSearch(token);

    } else if (matchPrefix("/c/", token)) {
      change(token);

    } else if (matchPrefix("/x/", token)) {
      extension(token);

    } else if (matchExact(MINE, token)) {
      String defaultScreenToken = Gerrit.getDefaultScreenToken();
      if (defaultScreenToken != null && !MINE.equals(defaultScreenToken)) {
        select(defaultScreenToken);
      } else {
        Gerrit.display(token, mine());
      }

    } else if (matchPrefix("/dashboard/", token)) {
      dashboard(token);

    } else if (matchPrefix(PROJECTS, token)) {
      projects(token);

    } else if (matchExact(SETTINGS, token)
        || matchPrefix("/settings/", token)
        || matchExact(MY_GROUPS, token)
        || matchExact("register", token)
        || matchExact(REGISTER, token)
        || matchPrefix("/register/", token)
        || matchPrefix("/VE/", token)
        || matchPrefix("VE,", token)
        || matchPrefix("/SignInFailure,", token)) {
      settings(token);

    } else if (matchPrefix("/admin/", token)) {
      admin(token);

    } else {
      Gerrit.display(token, new NotFoundScreen());
    }
  }

  private static void query(String token) {
    String s = skip(token);
    int c = s.indexOf(',');
    Screen screen;
    if (c >= 0) {
      String prefix = s.substring(0, c);
      if (s.substring(c).equals(",n,z")) {
        // Respect legacy token with max sortkey.
        screen = new QueryScreen(prefix, 0);
      } else {
        screen = new QueryScreen(prefix, Integer.parseInt(s.substring(c + 1)));
      }
    } else {
      screen = new QueryScreen(s, 0);
    }
    Gerrit.display(token, screen);
  }

  private static Screen mine() {
    if (Gerrit.isSignedIn()) {
      return new AccountDashboardScreen(Gerrit.getUserAccount()._accountId());
    }
    Screen r = new AccountDashboardScreen(null);
    r.setRequiresSignIn(true);
    return r;
  }

  private static void dashboard(String token) {
    String rest = skip(token);
    if (rest.matches("[0-9]+")) {
      int accountId = Integer.parseInt(rest);
      Gerrit.display(token, new AccountDashboardScreen(accountId));
      return;
    }

    if (rest.equals("self")) {
      if (Gerrit.isSignedIn()) {
        Gerrit.display(token, new AccountDashboardScreen(Gerrit.getUserAccount()._accountId()));
      } else {
        Screen s = new AccountDashboardScreen(null);
        s.setRequiresSignIn(true);
        Gerrit.display(token, s);
      }
      return;
    }

    if (rest.startsWith("?")) {
      Gerrit.display(token, new CustomDashboardScreen(rest.substring(1)));
      return;
    }

    Gerrit.display(token, new NotFoundScreen());
  }

  private static void projects(String token) {
    String rest = skip(token);
    int c = rest.indexOf(DASHBOARDS);
    if (0 <= c) {
      final String project = URL.decodePathSegment(rest.substring(0, c));
      rest = rest.substring(c);
      if (matchPrefix(DASHBOARDS, rest)) {
        final String dashboardId = skip(rest);
        GerritCallback<DashboardInfo> cb =
            new GerritCallback<DashboardInfo>() {
              @Override
              public void onSuccess(DashboardInfo result) {
                if (matchPrefix("/dashboard/", result.url())) {
                  String params = skip(result.url()).substring(1);
                  ProjectDashboardScreen dash =
                      new ProjectDashboardScreen(new Project.NameKey(project), params);
                  Gerrit.display(token, dash);
                }
              }

              @Override
              public void onFailure(Throwable caught) {
                if ("default".equals(dashboardId) && RestApi.isNotFound(caught)) {
                  Gerrit.display(
                      PageLinks.toChangeQuery(
                          PageLinks.projectQuery(new Project.NameKey(project))));
                } else {
                  super.onFailure(caught);
                }
              }
            };
        if ("default".equals(dashboardId)) {
          DashboardList.getDefault(new Project.NameKey(project), cb);
          return;
        }
        c = dashboardId.indexOf(":");
        if (0 <= c) {
          final String ref = URL.decodeQueryString(dashboardId.substring(0, c));
          final String path = URL.decodeQueryString(dashboardId.substring(c + 1));
          DashboardList.get(new Project.NameKey(project), ref + ":" + path, cb);
          return;
        }
      }
    }

    Gerrit.display(token, new NotFoundScreen());
  }

  private static void change(String token) {
    String rest = skip(token);
    int c = rest.lastIndexOf(',');
    String panel = null;
    if (0 <= c) {
      panel = rest.substring(c + 1);
      rest = rest.substring(0, c);
      int at = panel.lastIndexOf('@');
      if (at > 0) {
        rest += panel.substring(at);
        panel = panel.substring(0, at);
      }
    }

    ProjectChangeId id = ProjectChangeId.create(rest);
    rest = rest.length() > id.identifierLength() ? rest.substring(id.identifierLength() + 1) : "";

    if (rest.isEmpty()) {
      FileTable.Mode mode = FileTable.Mode.REVIEW;
      if (panel != null && (panel.equals("edit") || panel.startsWith("edit/"))) {
        mode = FileTable.Mode.EDIT;
        panel = null;
      }
      Gerrit.display(
          token,
          panel == null
              ? new ChangeScreen(
                  id.getProject(), id.getChangeId(), DiffObject.base(), null, false, mode)
              : new NotFoundScreen());
      return;
    }

    String psIdStr;
    int s = rest.indexOf('/');
    if (0 <= s) {
      psIdStr = rest.substring(0, s);
      rest = rest.substring(s + 1);
    } else {
      psIdStr = rest;
      rest = "";
    }

    DiffObject base = DiffObject.base();
    PatchSet.Id ps;
    int dotdot = psIdStr.indexOf("..");
    if (1 <= dotdot) {
      base = DiffObject.parse(id.getChangeId(), psIdStr.substring(0, dotdot));
      if (base == null) {
        Gerrit.display(token, new NotFoundScreen());
      }
      psIdStr = psIdStr.substring(dotdot + 2);
    }
    ps = toPsId(id.getChangeId(), psIdStr);

    if (!rest.isEmpty()) {
      DisplaySide side = DisplaySide.B;
      int line = 0;
      int at = rest.lastIndexOf('@');
      if (at > 0) {
        String l = rest.substring(at + 1);
        if (l.startsWith("a")) {
          side = DisplaySide.A;
          l = l.substring(1);
        }
        line = Integer.parseInt(l);
        rest = rest.substring(0, at);
      }
      Patch.Key p = new Patch.Key(ps, KeyUtil.decode(rest));
      patch(token, id.getProject(), base, p, side, line, panel);
    } else {
      if (panel == null) {
        Gerrit.display(
            token,
            new ChangeScreen(
                id.getProject(),
                id.getChangeId(),
                base,
                String.valueOf(ps.get()),
                false,
                FileTable.Mode.REVIEW));
      } else {
        Gerrit.display(token, new NotFoundScreen());
      }
    }
  }

  public static PatchSet.Id toPsId(Change.Id id, String psIdStr) {
    return new PatchSet.Id(id, psIdStr.equals("edit") ? 0 : Integer.parseInt(psIdStr));
  }

  private static void extension(String token) {
    ExtensionScreen view = new ExtensionScreen(skip(token));
    if (view.isFound()) {
      Gerrit.display(token, view);
    } else {
      Gerrit.display(token, new NotFoundScreen());
    }
  }

  private static void patch(
      String token,
      @Nullable Project.NameKey project,
      DiffObject base,
      Patch.Key id,
      DisplaySide side,
      int line,
      String panelType) {
    String panel = panelType;
    if (panel == null) {
      int c = token.lastIndexOf(',');
      panel = 0 <= c ? token.substring(c + 1) : "";
    }

    if ("".equals(panel) || /* DEPRECATED URL */ "cm".equals(panel)) {
      if (preferUnified()) {
        unified(token, project, base, id, side, line);
      } else {
        codemirror(token, base, project, id, side, line);
      }
    } else if ("sidebyside".equals(panel)) {
      codemirror(token, base, project, id, side, line);
    } else if ("unified".equals(panel)) {
      unified(token, project, base, id, side, line);
    } else if ("edit".equals(panel)) {
      if (!Patch.isMagic(id.get()) || Patch.COMMIT_MSG.equals(id.get())) {
        codemirrorForEdit(token, project, id, line);
      } else {
        Gerrit.display(token, new NotFoundScreen());
      }
    } else {
      Gerrit.display(token, new NotFoundScreen());
    }
  }

  private static boolean preferUnified() {
    return DiffView.UNIFIED_DIFF.equals(Gerrit.getUserPreferences().diffView())
        || (UserAgent.isPortrait() && UserAgent.isMobile());
  }

  private static void unified(
      final String token,
      final Project.NameKey project,
      final DiffObject base,
      final Patch.Key id,
      final DisplaySide side,
      final int line) {
    GWT.runAsync(
        new AsyncSplit(token) {
          @Override
          public void onSuccess() {
            Gerrit.display(
                token,
                new Unified(
                    project, base, DiffObject.patchSet(id.getParentKey()), id.get(), side, line));
          }
        });
  }

  private static void codemirror(
      final String token,
      final DiffObject base,
      @Nullable final Project.NameKey project,
      final Patch.Key id,
      final DisplaySide side,
      final int line) {
    GWT.runAsync(
        new AsyncSplit(token) {
          @Override
          public void onSuccess() {
            Gerrit.display(
                token,
                new SideBySide(
                    project, base, DiffObject.patchSet(id.getParentKey()), id.get(), side, line));
          }
        });
  }

  private static void codemirrorForEdit(
      final String token,
      @Nullable final Project.NameKey project,
      final Patch.Key id,
      final int line) {
    GWT.runAsync(
        new AsyncSplit(token) {
          @Override
          public void onSuccess() {
            Gerrit.display(token, new EditScreen(project, id, line));
          }
        });
  }

  private static void settings(String token) {
    GWT.runAsync(
        new AsyncSplit(token) {
          @Override
          public void onSuccess() {
            Gerrit.display(token, select());
          }

          private Screen select() {
            if (matchExact(SETTINGS, token)) {
              return new MyProfileScreen();
            }

            if (matchExact(SETTINGS_PREFERENCES, token)) {
              return new MyPreferencesScreen();
            }

            if (matchExact(SETTINGS_DIFF_PREFERENCES, token)) {
              return new MyDiffPreferencesScreen();
            }

            if (matchExact(SETTINGS_EDIT_PREFERENCES, token)) {
              return new MyEditPreferencesScreen();
            }

            if (matchExact(SETTINGS_PROJECTS, token)) {
              return new MyWatchedProjectsScreen();
            }

            if (matchExact(SETTINGS_CONTACT, token)) {
              return new MyContactInformationScreen();
            }

            if (matchExact(SETTINGS_SSHKEYS, token)) {
              return new MySshKeysScreen();
            }

            if (matchExact(SETTINGS_GPGKEYS, token) && Gerrit.info().gerrit().editGpgKeys()) {
              return new MyGpgKeysScreen();
            }

            if (matchExact(SETTINGS_WEBIDENT, token)) {
              return new MyIdentitiesScreen();
            }

            if (matchExact(SETTINGS_HTTP_PASSWORD, token)) {
              return new MyPasswordScreen();
            }

            if (matchExact(SETTINGS_OAUTH_TOKEN, token) && Gerrit.info().auth().isOAuth()) {
              return new MyOAuthTokenScreen();
            }

            if (matchExact(MY_GROUPS, token) || matchExact(SETTINGS_MYGROUPS, token)) {
              return new MyGroupsScreen();
            }

            if (matchExact(SETTINGS_AGREEMENTS, token)
                && Gerrit.info().auth().useContributorAgreements()) {
              return new MyAgreementsScreen();
            }

            if (matchExact(REGISTER, token)
                || matchExact("/register/", token)
                || matchExact("register", token)) {
              return new RegisterScreen(MINE);
            } else if (matchPrefix("/register/", token)) {
              return new RegisterScreen("/" + skip(token));
            }

            if (matchPrefix("/VE/", token) || matchPrefix("VE,", token)) {
              return new ValidateEmailScreen(skip(token));
            }

            if (matchExact(SETTINGS_NEW_AGREEMENT, token)) {
              return new NewAgreementScreen();
            }

            if (matchPrefix(SETTINGS_NEW_AGREEMENT + "/", token)) {
              return new NewAgreementScreen(skip(token));
            }

            if (matchPrefix(SETTINGS_EXTENSION, token)) {
              ExtensionSettingsScreen view = new ExtensionSettingsScreen(skip(token));
              if (view.isFound()) {
                return view;
              }
              return new NotFoundScreen();
            }

            return new NotFoundScreen();
          }
        });
  }

  private static void admin(String token) {
    GWT.runAsync(
        new AsyncSplit(token) {
          @Override
          public void onSuccess() {
            if (matchExact(ADMIN_GROUPS, token) || matchExact("/admin/groups", token)) {
              Gerrit.display(token, new GroupListScreen());

            } else if (matchPrefix(ADMIN_GROUPS, token)) {
              String rest = skip(token);
              if (rest.startsWith("?")) {
                Gerrit.display(token, new GroupListScreen(rest.substring(1)));
              } else {
                group();
              }

            } else if (matchPrefix("/admin/groups", token)) {
              String rest = skip(token);
              if (rest.startsWith("?")) {
                Gerrit.display(token, new GroupListScreen(rest.substring(1)));
              }

            } else if (matchExact(ADMIN_PROJECTS, token) || matchExact("/admin/projects", token)) {
              Gerrit.display(token, new ProjectListScreen());

            } else if (matchPrefix(ADMIN_PROJECTS, token)) {
              String rest = skip(token);
              if (rest.startsWith("?")) {
                Gerrit.display(token, new ProjectListScreen(rest.substring(1)));
              } else {
                Gerrit.display(token, selectProject());
              }

            } else if (matchPrefix("/admin/projects", token)) {
              String rest = skip(token);
              if (rest.startsWith("?")) {
                Gerrit.display(token, new ProjectListScreen(rest.substring(1)));
              }

            } else if (matchPrefix(ADMIN_PLUGINS, token) || matchExact("/admin/plugins", token)) {
              Gerrit.display(token, new PluginListScreen());

            } else if (matchExact(ADMIN_CREATE_PROJECT, token)
                || matchExact("/admin/create-project", token)) {
              Gerrit.display(token, new CreateProjectScreen());

            } else if (matchExact(ADMIN_CREATE_GROUP, token)
                || matchExact("/admin/create-group", token)) {
              Gerrit.display(token, new CreateGroupScreen());

            } else {
              Gerrit.display(token, new NotFoundScreen());
            }
          }

          private void group() {
            final String panel;
            final String group;

            if (matchPrefix("/admin/groups/uuid-", token)) {
              String p = skip(token);
              int c = p.indexOf(',');
              if (c < 0) {
                group = p;
                panel = null;
              } else {
                group = p.substring(0, c);
                panel = p.substring(c + 1);
              }
            } else if (matchPrefix(ADMIN_GROUPS, token)) {
              String p = skip(token);
              int c = p.indexOf(',');
              if (c < 0) {
                group = p;
                panel = null;
              } else {
                group = p.substring(0, c);
                panel = p.substring(c + 1);
              }
            } else {
              Gerrit.display(token, new NotFoundScreen());
              return;
            }

            GroupApi.getGroupDetail(
                group,
                new GerritCallback<GroupInfo>() {
                  @Override
                  public void onSuccess(GroupInfo group) {
                    if (panel == null || panel.isEmpty()) {
                      // The token does not say which group screen should be shown,
                      // as default for internal groups show the members, as default
                      // for external and system groups show the info screen (since
                      // for external and system groups the members cannot be
                      // shown in the web UI).
                      //
                      if (AccountGroup.isInternalGroup(group.getGroupUUID())) {
                        String newToken = toGroup(group.getGroupId(), AccountGroupScreen.MEMBERS);
                        Gerrit.display(newToken, new AccountGroupMembersScreen(group, newToken));
                      } else {
                        String newToken = toGroup(group.getGroupId(), AccountGroupScreen.INFO);
                        Gerrit.display(newToken, new AccountGroupInfoScreen(group, newToken));
                      }
                    } else if (AccountGroupScreen.INFO.equals(panel)) {
                      Gerrit.display(token, new AccountGroupInfoScreen(group, token));
                    } else if (AccountGroupScreen.MEMBERS.equals(panel)) {
                      Gerrit.display(token, new AccountGroupMembersScreen(group, token));
                    } else if (AccountGroupScreen.AUDIT_LOG.equals(panel)) {
                      Gerrit.display(token, new AccountGroupAuditLogScreen(group, token));
                    } else {
                      Gerrit.display(token, new NotFoundScreen());
                    }
                  }
                });
          }

          private Screen selectProject() {
            if (matchPrefix(ADMIN_PROJECTS, token)) {
              String rest = skip(token);
              int c = rest.lastIndexOf(',');
              if (c < 0) {
                return new ProjectInfoScreen(Project.NameKey.parse(rest));
              } else if (c == 0) {
                return new NotFoundScreen();
              }

              int q = rest.lastIndexOf('?');
              if (q > 0 && rest.lastIndexOf(',', q) > 0) {
                c = rest.substring(0, q - 1).lastIndexOf(',');
              }

              Project.NameKey k = Project.NameKey.parse(rest.substring(0, c));
              String panel = rest.substring(c + 1);

              if (ProjectScreen.INFO.equals(panel)) {
                return new ProjectInfoScreen(k);
              }

              if (ProjectScreen.BRANCHES.equals(panel)
                  || matchPrefix(ProjectScreen.BRANCHES, panel)) {
                return new ProjectBranchesScreen(k);
              }

              if (ProjectScreen.TAGS.equals(panel) || matchPrefix(ProjectScreen.TAGS, panel)) {
                return new ProjectTagsScreen(k);
              }

              if (ProjectScreen.ACCESS.equals(panel)) {
                return new ProjectAccessScreen(k);
              }

              if (ProjectScreen.DASHBOARDS.equals(panel)) {
                return new ProjectDashboardsScreen(k);
              }
            }
            return new NotFoundScreen();
          }
        });
  }

  private static boolean matchExact(String want, String token) {
    return token.equals(want);
  }

  private static int prefixlen;

  private static boolean matchPrefix(String want, String token) {
    if (token.startsWith(want)) {
      prefixlen = want.length();
      return true;
    }
    return false;
  }

  private static String skip(String token) {
    return token.substring(prefixlen);
  }

  private abstract static class AsyncSplit implements RunAsyncCallback {
    private final boolean isReloadUi;
    protected final String token;

    protected AsyncSplit(String token) {
      this.isReloadUi = wasStartedByReloadUI;
      this.token = token;
    }

    @Override
    public final void onFailure(Throwable reason) {
      if (!isReloadUi && "HTTP download failed with status 404".equals(reason.getMessage())) {
        // The server was upgraded since we last download the main script,
        // so the pointers to the splits aren't valid anymore.  Force the
        // page to reload itself and pick up the new code.
        //
        Gerrit.upgradeUI(token);
      } else {
        new ErrorDialog(reason).center();
      }
    }
  }

  private static void docSearch(String token) {
    GWT.runAsync(
        new AsyncSplit(token) {
          @Override
          public void onSuccess() {
            Gerrit.display(token, new DocScreen(skip(token)));
          }
        });
  }
}
