syntax = "proto3";

package nominal.blob_storage_service.v1;

import "buf/validate/validate.proto";
import "google/api/annotations.proto";
import "nominal/gen/v1/alias.proto";

// This is used to identify any type of blob that will be in object storage.
message ResourceIdentifier {
  string rid = 1 [
    (nominal.gen.v1.alias) = {java_name: "com.palantir.ri.ResourceIdentifier"},
    (buf.validate.field) = {required: true},
    // Regex taken from https://github.com/palantir/resource-identifier?tab=readme-ov-file#format
    (buf.validate.field).string.pattern = "^ri\\.[a-z][a-z0-9\\-]*\\.([a-z0-9][a-z0-9\\-]*)?\\.[a-z][a-z0-9\\-]*\\.[a-zA-Z0-9\\-\\._]+$"
  ];
}

// file_name and owning_rid should be consistent across all requests for a byte stream
// permission on the uploaded blob is tied to associated owning_rid
// when making a call to upload stream request, the assumption is that the user already has
// auth on the owning_rid, and we will throw a permission error if this doesn't hold
message UploadBlobStreamRequest {
  ResourceIdentifier owning_rid = 1 [(buf.validate.field) = {required: true}];
  string file_name = 2 [(buf.validate.field) = {required: true}];
  // when set to true, ensure_unique will attach the current timestamp to the file name
  // this will ensure that we do not overwrite an existing file in blob storage
  bool ensure_unique = 3 [(buf.validate.field) = {required: true}];

  bytes content = 4 [(buf.validate.field) = {required: true}];
}

message UploadBlobStreamResponse {
  // This is the key that can be used in a retrieve blob request in order
  // to retrieve this specific blob. If ensure_unique is not set, this will match
  // the file name provided in UploadBlobStreamRequest
  string file_name = 1;
}

message GetSignedUrlForBlobRequest {
  ResourceIdentifier owning_rid = 1 [(buf.validate.field) = {required: true}];
  string file_name = 2 [(buf.validate.field) = {required: true}];
}

message GetSignedUrlForBlobResponse {
  // This is a short lived signed url that can be used by the client to retrieve
  // the object
  string url = 1;
}

// Service for storing and retrieving blobs in object storage with workspace-based authorization.
service BlobStorageService {
  // Upload a blob using streaming. The blob will be stored with authorization checks
  // based on the provided owningRid.
  rpc UploadBlobStream(stream UploadBlobStreamRequest) returns (UploadBlobStreamResponse) {
    option (google.api.http) = {
      post: "/blobs/v1"
      body: "*"
    };
  }

  // Retrieve a signed URL for downloading a blob. The URL is valid for 15 minutes.
  rpc GetSignedUrlForBlob(GetSignedUrlForBlobRequest) returns (GetSignedUrlForBlobResponse) {
    option (google.api.http) = {
      post: "/blobs/v1/get"
      body: "*"
    };
  }
}
