// Copyright (C) 2013 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.entities;

import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.UsedAt;
import java.util.List;

/** Constants and utilities for Gerrit-specific ref names. */
public class RefNames {
  public static final String HEAD = "HEAD";

  public static final String REFS = "refs/";

  public static final String REFS_HEADS = "refs/heads/";

  public static final String REFS_TAGS = "refs/tags/";

  public static final String REFS_CHANGES = "refs/changes/";

  public static final String REFS_META = "refs/meta/";

  /** Note tree listing commits we refuse {@code refs/meta/reject-commits} */
  public static final String REFS_REJECT_COMMITS = "refs/meta/reject-commits";

  /** Configuration settings for a project {@code refs/meta/config} */
  public static final String REFS_CONFIG = "refs/meta/config";

  /** Note tree listing external IDs */
  public static final String REFS_EXTERNAL_IDS = "refs/meta/external-ids";

  /** Magic user branch in All-Users {@code refs/users/self} */
  public static final String REFS_USERS_SELF = "refs/users/self";

  /** Default user preference settings */
  public static final String REFS_USERS_DEFAULT = RefNames.REFS_USERS + "default";

  /** Configurations of project-specific dashboards (canned search queries). */
  public static final String REFS_DASHBOARDS = "refs/meta/dashboards/";

  /** Sequence counters in NoteDb. */
  public static final String REFS_SEQUENCES = "refs/sequences/";

  /** NoteDb schema version number. */
  public static final String REFS_VERSION = "refs/meta/version";

  /**
   * Prefix applied to merge commit base nodes.
   *
   * <p>References in this directory should take the form {@code refs/cache-automerge/xx/yyyy...}
   * where xx is the first two digits of the merge commit's object name, and yyyyy... is the
   * remaining 38. The reference should point to a treeish that is the automatic merge result of the
   * merge commit's parents.
   */
  public static final String REFS_CACHE_AUTOMERGE = "refs/cache-automerge/";

  /** Suffix of a meta ref in the NoteDb. */
  public static final String META_SUFFIX = "/meta";

  /** Suffix of a ref that stores robot comments in the NoteDb. */
  public static final String ROBOT_COMMENTS_SUFFIX = "/robot-comments";

  public static final String EDIT_PREFIX = "edit-";

  /*
   * The following refs contain an account ID and should be visible only to that account.
   *
   * Parsing the account ID from the ref is implemented in Account.Id#fromRef(String). This ensures
   * that VisibleRefFilter hides those refs from other users.
   *
   * This applies to:
   * - User branches (e.g. 'refs/users/23/1011123')
   * - Draft comment refs (e.g. 'refs/draft-comments/73/67473/1011123')
   * - Starred changes refs (e.g. 'refs/starred-changes/73/67473/1011123')
   */

  /** Preference settings for a user {@code refs/users} */
  public static final String REFS_USERS = "refs/users/";

  /** NoteDb ref for a group {@code refs/groups} */
  public static final String REFS_GROUPS = "refs/groups/";

  /** NoteDb ref for the NoteMap of all group names */
  public static final String REFS_GROUPNAMES = "refs/meta/group-names";

  /**
   * NoteDb ref for deleted groups {@code refs/deleted-groups}. This ref namespace is foreseen as an
   * attic for deleted groups (it's reserved but not used yet)
   */
  public static final String REFS_DELETED_GROUPS = "refs/deleted-groups/";

  /** Draft inline comments of a user on a change */
  public static final String REFS_DRAFT_COMMENTS = "refs/draft-comments/";

  /** A change starred by a user */
  public static final String REFS_STARRED_CHANGES = "refs/starred-changes/";

  /**
   * List of refs managed by Gerrit. Covers all Gerrit internal refs.
   *
   * <p><b>Caution</b> Any ref not in this list will be served if the user was granted a READ
   * permission on it using Gerrit's permission model.
   */
  public static final ImmutableList<String> GERRIT_REFS =
      ImmutableList.of(
          REFS_CHANGES,
          REFS_EXTERNAL_IDS,
          REFS_CACHE_AUTOMERGE,
          REFS_DRAFT_COMMENTS,
          REFS_DELETED_GROUPS,
          REFS_SEQUENCES,
          REFS_GROUPS,
          REFS_GROUPNAMES,
          REFS_USERS,
          REFS_STARRED_CHANGES,
          REFS_REJECT_COMMITS);

  private static final Splitter SPLITTER = Splitter.on("/");

  public static String fullName(String ref) {
    return (ref.startsWith(REFS) || ref.equals(HEAD)) ? ref : REFS_HEADS + ref;
  }

  public static final String shortName(String ref) {
    if (ref.startsWith(REFS_HEADS)) {
      return ref.substring(REFS_HEADS.length());
    } else if (ref.startsWith(REFS_TAGS)) {
      return ref.substring(REFS_TAGS.length());
    }
    return ref;
  }

  /**
   * Warning: Change refs have to manually be advertised in {@code
   * com.google.gerrit.server.permissions.DefaultRefFilter}; this should be done when adding new
   * change refs.
   */
  public static String changeMetaRef(Change.Id id) {
    StringBuilder r = newStringBuilder().append(REFS_CHANGES);
    return shard(id.get(), r).append(META_SUFFIX).toString();
  }

  public static String patchSetRef(PatchSet.Id id) {
    StringBuilder r = newStringBuilder().append(REFS_CHANGES);
    return shard(id.changeId().get(), r).append('/').append(id.get()).toString();
  }

  public static String changeRefPrefix(Change.Id id) {
    StringBuilder r = newStringBuilder().append(REFS_CHANGES);
    return shard(id.get(), r).append('/').toString();
  }

  public static String robotCommentsRef(Change.Id id) {
    StringBuilder r = newStringBuilder().append(REFS_CHANGES);
    return shard(id.get(), r).append(ROBOT_COMMENTS_SUFFIX).toString();
  }

  public static boolean isNoteDbMetaRef(String ref) {
    if (ref.startsWith(REFS_CHANGES)
        && (ref.endsWith(META_SUFFIX) || ref.endsWith(ROBOT_COMMENTS_SUFFIX))) {
      return true;
    }
    if (ref.startsWith(REFS_DRAFT_COMMENTS) || ref.startsWith(REFS_STARRED_CHANGES)) {
      return true;
    }
    return false;
  }

  /** True if the provided ref is in {@code refs/changes/*}. */
  public static boolean isRefsChanges(String ref) {
    return ref.startsWith(REFS_CHANGES);
  }

  /** True if the provided ref is in {@code refs/sequences/*}. */
  public static boolean isSequenceRef(String ref) {
    return ref.startsWith(REFS_SEQUENCES);
  }

  /** True if the provided ref is in {@code refs/tags/*}. */
  public static boolean isTagRef(String ref) {
    return ref.startsWith(REFS_TAGS);
  }

  /** True if the provided ref is {@link REFS_EXTERNAL_IDS}. */
  public static boolean isExternalIdRef(String ref) {
    return REFS_EXTERNAL_IDS.equals(ref);
  }

  public static String refsGroups(AccountGroup.UUID groupUuid) {
    return REFS_GROUPS + shardUuid(groupUuid.get());
  }

  public static String refsDeletedGroups(AccountGroup.UUID groupUuid) {
    return REFS_DELETED_GROUPS + shardUuid(groupUuid.get());
  }

  public static String refsUsers(Account.Id accountId) {
    StringBuilder r = newStringBuilder().append(REFS_USERS);
    return shard(accountId.get(), r).toString();
  }

  public static String refsDraftComments(Change.Id changeId, Account.Id accountId) {
    return buildRefsPrefix(REFS_DRAFT_COMMENTS, changeId.get()).append(accountId.get()).toString();
  }

  public static String refsDraftCommentsPrefix(Change.Id changeId) {
    return buildRefsPrefix(REFS_DRAFT_COMMENTS, changeId.get()).toString();
  }

  public static String refsStarredChanges(Change.Id changeId, Account.Id accountId) {
    return buildRefsPrefix(REFS_STARRED_CHANGES, changeId.get()).append(accountId.get()).toString();
  }

  public static String refsStarredChangesPrefix(Change.Id changeId) {
    return buildRefsPrefix(REFS_STARRED_CHANGES, changeId.get()).toString();
  }

  private static StringBuilder buildRefsPrefix(String prefix, int id) {
    StringBuilder r = newStringBuilder().append(prefix);
    return shard(id, r).append('/');
  }

  public static String refsCacheAutomerge(String hash) {
    return REFS_CACHE_AUTOMERGE + hash.substring(0, 2) + '/' + hash.substring(2);
  }

  @Nullable
  public static String shard(int id) {
    if (id < 0) {
      return null;
    }
    return shard(id, newStringBuilder()).toString();
  }

  private static StringBuilder shard(int id, StringBuilder sb) {
    int n = id % 100;
    if (n < 10) {
      sb.append('0');
    }
    sb.append(n);
    sb.append('/');
    sb.append(id);
    return sb;
  }

  @UsedAt(UsedAt.Project.PLUGINS_ALL)
  public static String shardUuid(String uuid) {
    if (uuid == null || uuid.length() < 2) {
      throw new IllegalArgumentException("UUIDs must consist of at least two characters");
    }
    return uuid.substring(0, 2) + '/' + uuid;
  }

  /**
   * Returns reference for this change edit with sharded user and change number:
   * refs/users/UU/UUUU/edit-CCCC/P.
   *
   * @param accountId account id
   * @param changeId change number
   * @param psId patch set number
   * @return reference for this change edit
   */
  public static String refsEdit(Account.Id accountId, Change.Id changeId, PatchSet.Id psId) {
    return refsEditPrefix(accountId, changeId) + psId.get();
  }

  /**
   * Returns reference prefix for this change edit with sharded user and change number:
   * refs/users/UU/UUUU/edit-CCCC/.
   *
   * @param accountId account id
   * @param changeId change number
   * @return reference prefix for this change edit
   */
  public static String refsEditPrefix(Account.Id accountId, Change.Id changeId) {
    return refsEditPrefix(accountId) + changeId.get() + '/';
  }

  public static String refsEditPrefix(Account.Id accountId) {
    return refsUsers(accountId) + '/' + EDIT_PREFIX;
  }

  public static boolean isRefsEdit(String ref) {
    return ref != null && ref.startsWith(REFS_USERS) && ref.contains(EDIT_PREFIX);
  }

  public static boolean isRefsUsers(String ref) {
    return ref.startsWith(REFS_USERS);
  }

  public static boolean isRefsUsersSelf(String ref, boolean isAllUsers) {
    return isAllUsers && REFS_USERS_SELF.equals(ref);
  }

  /**
   * Whether the ref is a group branch that stores NoteDb data of a group. Returns {@code true} for
   * all refs that start with {@code refs/groups/}.
   */
  public static boolean isRefsGroups(String ref) {
    return ref.startsWith(REFS_GROUPS);
  }

  /**
   * Whether the ref is a group branch that stores NoteDb data of a deleted group. Returns {@code
   * true} for all refs that start with {@code refs/deleted-groups/}.
   */
  public static boolean isRefsDeletedGroups(String ref) {
    return ref.startsWith(REFS_DELETED_GROUPS);
  }

  /** Returns true if the provided ref is for draft comments. */
  public static boolean isRefsDraftsComments(String ref) {
    return ref.startsWith(REFS_DRAFT_COMMENTS);
  }

  /** Returns true if the provided ref is for starred changes. */
  public static boolean isRefsStarredChanges(String ref) {
    return ref.startsWith(REFS_STARRED_CHANGES);
  }

  /**
   * Whether the ref is used for storing group data in NoteDb. Returns {@code true} for all group
   * branches, refs/meta/group-names and deleted group branches.
   */
  public static boolean isGroupRef(String ref) {
    return isRefsGroups(ref) || isRefsDeletedGroups(ref) || REFS_GROUPNAMES.equals(ref);
  }

  /** Whether the ref is the configuration branch, i.e. {@code refs/meta/config}, for a project. */
  public static boolean isConfigRef(String ref) {
    return REFS_CONFIG.equals(ref);
  }

  /** Whether the ref is the version branch, i.e. {@code refs/meta/version}. */
  public static boolean isVersionRef(String ref) {
    return REFS_VERSION.equals(ref);
  }

  /** Whether the ref is an auto-merge ref. */
  public static boolean isAutoMergeRef(String ref) {
    return ref.startsWith(REFS_CACHE_AUTOMERGE);
  }

  /** Whether the ref is an reject commit ref, i.e. {@code refs/meta/reject-commits} */
  public static boolean isRejectCommitsRef(String ref) {
    return REFS_REJECT_COMMITS.equals(ref);
  }

  /**
   * Whether the ref is managed by Gerrit. Covers all Gerrit-internal refs like refs/cache-automerge
   * and refs/meta as well as refs/changes. Does not cover user-created refs like branches or custom
   * ref namespaces like refs/my-company.
   *
   * <p>Any ref for which this method evaluates to true will be served to users who have the {@code
   * ACCESS_DATABASE} capability.
   *
   * <p><b>Caution</b> Any ref not in this list will be served if the user was granted a READ
   * permission on it using Gerrit's permission model.
   */
  public static boolean isGerritRef(String ref) {
    return GERRIT_REFS.stream().anyMatch(internalRef -> ref.startsWith(internalRef));
  }

  @Nullable
  static Integer parseShardedRefPart(String name) {
    if (name == null) {
      return null;
    }

    List<String> parts = SPLITTER.splitToList(name);
    int n = parts.size();
    if (n < 2) {
      return null;
    }

    // Last 2 digits.
    int le;
    for (le = 0; le < parts.get(0).length(); le++) {
      if (!Character.isDigit(parts.get(0).charAt(le))) {
        return null;
      }
    }
    if (le != 2) {
      return null;
    }

    // Full ID.
    int ie;
    for (ie = 0; ie < parts.get(1).length(); ie++) {
      if (!Character.isDigit(parts.get(1).charAt(ie))) {
        if (ie == 0) {
          return null;
        }
        break;
      }
    }

    int shard = Integer.parseInt(parts.get(0));
    int id = Integer.parseInt(parts.get(1).substring(0, ie));

    if (id % 100 != shard) {
      return null;
    }
    return id;
  }

  @UsedAt(UsedAt.Project.PLUGINS_ALL)
  @Nullable
  public static String parseShardedUuidFromRefPart(String name) {
    if (name == null) {
      return null;
    }

    List<String> parts = SPLITTER.splitToList(name);
    int n = parts.size();
    if (n != 2) {
      return null;
    }

    // First 2 chars.
    if (parts.get(0).length() != 2) {
      return null;
    }

    // Full UUID.
    String uuid = parts.get(1);
    if (!uuid.startsWith(parts.get(0))) {
      return null;
    }

    return uuid;
  }

  /**
   * Skips a sharded ref part at the beginning of the name.
   *
   * <p>E.g.: "01/1" -> "", "01/1/" -> "/", "01/1/2" -> "/2", "01/1-edit" -> "-edit"
   *
   * @param name ref part name
   * @return the rest of the name, {@code null} if the ref name part doesn't start with a valid
   *     sharded ID
   */
  @Nullable
  static String skipShardedRefPart(String name) {
    if (name == null) {
      return null;
    }

    List<String> parts = SPLITTER.splitToList(name);
    int n = parts.size();
    if (n < 2) {
      return null;
    }

    // Last 2 digits.
    int le;
    for (le = 0; le < parts.get(0).length(); le++) {
      if (!Character.isDigit(parts.get(0).charAt(le))) {
        return null;
      }
    }
    if (le != 2) {
      return null;
    }

    // Full ID.
    int ie;
    for (ie = 0; ie < parts.get(1).length(); ie++) {
      if (!Character.isDigit(parts.get(1).charAt(ie))) {
        if (ie == 0) {
          return null;
        }
        break;
      }
    }

    int shard = Integer.parseInt(parts.get(0));
    int id = Integer.parseInt(parts.get(1).substring(0, ie));

    if (id % 100 != shard) {
      return null;
    }

    return name.substring(2 + 1 + ie); // 2 for the length of the shard, 1 for the '/'
  }

  /**
   * Parses an ID that follows a sharded ref part at the beginning of the name.
   *
   * <p>E.g.: "01/1/2" -> 2, "01/1/2/4" -> 2, ""01/1/2-edit" -> 2
   *
   * @param name ref part name
   * @return ID that follows the sharded ref part at the beginning of the name, {@code null} if the
   *     ref name part doesn't start with a valid sharded ID or if no valid ID follows the sharded
   *     ref part
   */
  @Nullable
  static Integer parseAfterShardedRefPart(String name) {
    String rest = skipShardedRefPart(name);
    if (rest == null || !rest.startsWith("/")) {
      return null;
    }

    rest = rest.substring(1);

    int ie;
    for (ie = 0; ie < rest.length(); ie++) {
      if (!Character.isDigit(rest.charAt(ie))) {
        break;
      }
    }
    if (ie == 0) {
      return null;
    }
    return Integer.parseInt(rest.substring(0, ie));
  }

  @Nullable
  public static Integer parseRefSuffix(String name) {
    if (name == null) {
      return null;
    }
    int i = name.length();
    while (i > 0) {
      char c = name.charAt(i - 1);
      if (c == '/') {
        break;
      } else if (!Character.isDigit(c)) {
        return null;
      }
      i--;
    }
    if (i == 0) {
      return null;
    }
    return Integer.valueOf(name.substring(i));
  }

  private static StringBuilder newStringBuilder() {
    // Many refname types in this file are always are longer than the default of 16 chars, so
    // presize StringBuilders larger by default. This hurts readability less than accurate
    // calculations would, at a negligible cost to memory overhead.
    return new StringBuilder(64);
  }

  private RefNames() {}
}
