// 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 toProjectAcceess(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 toAssigneeQuery(String fullname) {
    return toChangeQuery(op("assignee", fullname));
  }

  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() {}
}
