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

import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Change.Status;
import com.google.gerrit.entities.KeyUtil;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project;

public class PageLinks {
  public static final String PROJECT_CHANGE_DELIMITER = "/+/";

  public static final String SETTINGS = "/settings/";
  public static final String SETTINGS_PREFERENCES = "/settings/preferences";
  public static final String SETTINGS_DIFF_PREFERENCES = "/settings/diff-preferences";
  public static final String SETTINGS_EDIT_PREFERENCES = "/settings/edit-preferences";
  public static final String SETTINGS_SSHKEYS = "/settings/ssh-keys";
  public static final String SETTINGS_GPGKEYS = "/settings/gpg-keys";
  public static final String SETTINGS_HTTP_PASSWORD = "/settings/http-password";
  public static final String SETTINGS_OAUTH_TOKEN = "/settings/oauth-token";
  public static final String SETTINGS_WEBIDENT = "/settings/web-identities";
  public static final String SETTINGS_MYGROUPS = "/settings/group-memberships";
  public static final String SETTINGS_AGREEMENTS = "/settings/agreements";
  public static final String SETTINGS_CONTACT = "/settings/contact";
  public static final String SETTINGS_PROJECTS = "/settings/projects";
  public static final String SETTINGS_NEW_AGREEMENT = "/settings/new-agreement";
  public static final String SETTINGS_EXTENSION = "/settings/x/";
  public static final String REGISTER = "/register";

  public static final String MINE = "/";
  public static final String QUERY = "/q/";
  public static final String PROJECTS = "/projects/";
  public static final String DASHBOARDS = ",dashboards/";
  public static final String ADMIN_GROUPS = "/admin/groups/";
  public static final String ADMIN_CREATE_GROUP = "/admin/create-group/";
  public static final String ADMIN_PROJECTS = "/admin/projects/";
  public static final String ADMIN_CREATE_PROJECT = "/admin/create-project/";
  public static final String ADMIN_PLUGINS = "/admin/plugins/";
  public static final String MY_GROUPS = "/groups/self";
  public static final String DOCUMENTATION = "/Documentation/";

  public static String toChangeInEditMode(@Nullable Project.NameKey project, Change.Id c) {
    return toChangeNoSlash(project, c) + ",edit/";
  }

  public static String toChange(@Nullable Project.NameKey project, Change.Id c) {
    return toChangeNoSlash(project, c) + "/";
  }

  public static String toChange(@Nullable Project.NameKey project, Change.Id c, String p) {
    return toChange(project, c) + p;
  }

  public static String toChange(
      @Nullable Project.NameKey project, Change.Id c, String b, String p) {
    String u = toChange(project, c);
    if (b != null) {
      u += b + "..";
    }
    u += p;
    return u;
  }

  public static String toChangeId(@Nullable Project.NameKey project, Change.Id c) {
    if (project == null) {
      return String.valueOf(c.get());
    }
    return project.get() + PROJECT_CHANGE_DELIMITER + c.get();
  }

  public static String toChange(@Nullable Project.NameKey project, PatchSet.Id ps) {
    return toChange(project, ps.changeId()) + ps.getId();
  }

  public static String toProject(Project.NameKey p) {
    return ADMIN_PROJECTS + p.get();
  }

  public static String toProjectAccess(Project.NameKey p) {
    return ADMIN_PROJECTS + p.get() + ",access";
  }

  public static String toProjectBranches(Project.NameKey p) {
    return ADMIN_PROJECTS + p.get() + ",branches";
  }

  public static String toProjectTags(Project.NameKey p) {
    return ADMIN_PROJECTS + p.get() + ",tags";
  }

  public static String toAccountQuery(String fullname, Status status) {
    return toChangeQuery(op("owner", fullname) + " " + status(status));
  }

  public static String toCustomDashboard(String params) {
    return "/dashboard/?" + params;
  }

  public static String toProjectDashboards(Project.NameKey proj) {
    return ADMIN_PROJECTS + proj.get() + ",dashboards";
  }

  public static String toChangeQuery(String query) {
    return QUERY + KeyUtil.encode(query);
  }

  public static String toProjectDashboard(Project.NameKey name, String id) {
    return PROJECTS + name.get() + DASHBOARDS + id;
  }

  public static String toProjectDefaultDashboard(Project.NameKey name) {
    return PROJECTS + name.get() + DASHBOARDS + "default";
  }

  public static String projectQuery(Project.NameKey proj) {
    return op("project", proj.get());
  }

  public static String projectQuery(Project.NameKey proj, Status status) {
    return status(status) + " " + op("project", proj.get());
  }

  public static String topicQuery(Status status, String topic) {
    switch (status) {
      case ABANDONED:
        return toChangeQuery(status(status) + " " + op("topic", topic));
      case MERGED:
      case NEW:
        return toChangeQuery(
            op("topic", topic) + " (" + status(Status.NEW) + " OR " + status(Status.MERGED) + ")");
    }
    return toChangeQuery(status(status) + " " + op("topic", topic));
  }

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

  public static String toSettings(String pluginName, String path) {
    return SETTINGS_EXTENSION + pluginName + "/" + path;
  }

  public static String toDocumentationQuery(String query) {
    return DOCUMENTATION + KeyUtil.encode(query);
  }

  private static String status(Status status) {
    switch (status) {
      case ABANDONED:
        return "status:abandoned";
      case MERGED:
        return "status:merged";
      case NEW:
      default:
        return "status:open";
    }
  }

  private static String toChangeNoSlash(@Nullable Project.NameKey project, Change.Id c) {
    if (project != null) {
      return "/c/" + project.get() + PROJECT_CHANGE_DELIMITER + c;
    }
    return "/c/" + c;
  }

  public static String op(String op, int value) {
    return op + ":" + value;
  }

  public static String op(String op, String value) {
    if (isSingleWord(value)) {
      return op + ":" + value;
    }
    return op + ":\"" + value + "\"";
  }

  private static boolean isSingleWord(String value) {
    if (value.startsWith("-")) {
      return false;
    }
    return value.matches("[^\u0000-\u0020!\"#$%&'():;?\\[\\]{}~]+");
  }

  protected PageLinks() {}
}
