syntax = "proto3";

package mesh.v1;

import "mesh/v1/git_model.proto";

option go_package = "atlassian.com/bitbucket/mesh/rpc/v1";
option java_multiple_files = true;
option java_outer_classname = "RefProtos";
option java_package = "com.atlassian.bitbucket.mesh.rpc.v1";

message RpcCheckFormatRequest {
  RpcGitTimeouts timeouts = 1;

  bytes ref_id = 10;
}

message RpcCheckFormatResponse {
}

message RpcCreateBranchRequest {
  string repository = 1;
  RpcGitTimeouts timeouts = 3;

  bytes name = 10;
  RpcPerson author = 11;
  //The commit-ish (ref name, commit hash) the new branch should point to. If not specified, or left blank,
  //the new branch will be created from the tip of the default branch.
  optional bytes start_point = 12;
  bool force = 13;
  bool reflog = 14;
}

message RpcCreateBranchResponse {
  RpcBranch branch = 1;
}

message RpcCreateTagRequest {
  string repository = 1;
  RpcGitTimeouts timeouts = 3;

  bytes name = 10;
  RpcPerson author = 11;
  bytes message = 12;
  //The object to tag, which can be specified as a ref name or the hash of any object. If not specified, or
  //left blank, the tip of the default branch will be tagged.
  optional bytes start_point = 13;
  bool force = 14;
  RpcTagType type = 15;
}

message RpcCreateTagResponse {
  RpcTag tag = 1;
}

message RpcDeleteBranchRequest {
  string repository = 1;
  RpcGitTimeouts timeouts = 3;

  bytes name = 10;
  bool force = 11;
  RpcPerson author = 12;
}

message RpcDeleteBranchResponse {
}

message RpcDeleteTagRequest {
  string repository = 1;
  RpcGitTimeouts timeouts = 3;

  bytes name = 10;
  RpcPerson author = 11;
}

message RpcDeleteTagResponse {
}

/* A git object that is not a tag for a AnnotatedTagResponse */
message RpcNonTag {
  bytes object_id = 1;
  RpcGitObjectType object_type = 2;
}

/*
 * A ref update to apply. The old_hash and new_hash indicate how the specified ref should be updated and allow for
 * significant flexibility. For the following examples, "zero" means the null SHA (40 or 64 0s).
 * old_hash set; new_hash set: Update a ref. If the ref does not exist, or has a different hash, the update fails
 * old_hash set; new_hash unset: Delete a ref. If the ref does not exist, or has a different hash, deletion fails
 * old_hash set; new_hash zero: Same as if new_hash is unset
 * old_hash zero; new_hash set: Create a ref. If the ref already exists, the update fails
 * old_hash zero; new_hash unset: Delete a ref, regardless of the current hash
 * old_hash zero; new_hash zero: Delete a ref, regardless of the current hash
 * old_hash unset; new_hash set: Create or update a ref. Updates are applied regardless of the current hash
 * old_hash unset; new_hash unset: Delete a ref, regardless of the current hash
 * old_hash unset; new_hash zero: Delete a ref, regardless of the current hash
 */
message RpcProposedRefUpdate {
  bytes ref_id = 1;
  optional string old_hash = 2;
  optional string new_hash = 3;
}

message RpcResolveAnnotatedTagRequest {
  string repository = 1;
  RpcGitTimeouts timeouts = 3;

  int32 max_message_length = 10;
  repeated bytes tag_ids = 11;
}

message RpcResolveAnnotatedTagResponse {
  oneof result_oneof {
    RpcAnnotatedTag tag = 1;
    bytes missing = 2;
    RpcNonTag non_tag = 3;
  }
}

message RpcResolveAnnotatedTagResponseFragment {
  repeated RpcResolveAnnotatedTagResponse responses = 1;
}

message RpcResolveDefaultBranchRequest {
  string repository = 1;
  RpcGitTimeouts timeouts = 2;
}

message RpcResolveDefaultBranchResponse {
  RpcBranch branch = 1;
}

message RpcResolvedRef {
  //The request ID from which the ref was resolved. This will be an entry from one of the ID lists (branch_ids,
  //ref_ids or tag_ids).
  bytes ref_id = 3;

  oneof ref_oneof {
    RpcBranch branch = 1;
    RpcTag tag = 2;
  }
}

message RpcResolveRefsRequest {
  string repository = 1;
  RpcGitTimeouts timeouts = 3;

  repeated bytes branch_ids = 10;
  repeated bytes tag_ids = 11;
  repeated bytes ref_ids = 12;
}

message RpcResolveRefsResponse {
  //Protobuf maps don't support bytes for keys, so this has to use a list of entries instead.
  repeated RpcResolvedRef resolved_refs = 1;
}

message RpcUpdateRefRequest {
  string repository = 1;
  RpcGitTimeouts timeouts = 3;

  //The update to apply
  RpcProposedRefUpdate ref_update = 10;
}

message RpcUpdateRefResponse {
  //Empty. If the ref update fails, an error will be returned in trailer metadata
}

message RpcUpdateRefsRequest {
  string repository = 1;
  RpcGitTimeouts timeouts = 3;

  //The updates to apply
  repeated RpcProposedRefUpdate ref_updates = 10;
  //Indicates whether updates should be applied in an all-or-nothing or best effort manner
  bool transactional = 11;
}

message RpcUpdateRefsResponse {
  repeated bytes failed_ref_ids = 1;
}
