syntax = "proto3";

package forest.v1;

message AnnotateReleaseRequest {
  string artifact_id = 1;
  map<string, string> metadata = 2;
  Source source = 3;
  ArtifactContext context = 4;
  Project project = 5;
  Ref ref = 6;
}
message AnnotateReleaseResponse {
  Artifact artifact = 1;
}

message GetArtifactBySlugRequest {
  string slug = 1;
}
message GetArtifactBySlugResponse {
  Artifact artifact = 1;
}
message GetArtifactsByProjectRequest {
  Project project = 1;
}
message GetArtifactsByProjectResponse {
  repeated Artifact artifact = 1;
}

message ReleaseRequest {
  string artifact_id = 1;
  repeated string destinations = 2;
  repeated string environments = 3;
  bool force = 4;
  // When true, use the project's release pipeline (DAG) instead of
  // deploying directly to the specified destinations/environments.
  bool use_pipeline = 5;
}
message ReleaseResponse {
  // List of release intents created (one per destination)
  repeated ReleaseIntent intents = 1;
}

message ReleaseIntent {
  string release_intent_id = 1;
  string destination = 2;
  string environment = 3;
}

message WaitReleaseRequest {
  string release_intent_id = 1;
}

message WaitReleaseEvent {
  oneof event {
    ReleaseStatusUpdate status_update = 1;
    ReleaseLogLine log_line = 2;
  }
}

message ReleaseStatusUpdate {
  string destination = 1;
  string status = 2;
}

message ReleaseLogLine {
  string destination = 1;
  string line = 2;
  string timestamp = 3;
  LogChannel channel = 4;
}

enum LogChannel {
  LOG_CHANNEL_UNSPECIFIED = 0;
  LOG_CHANNEL_STDOUT = 1;
  LOG_CHANNEL_STDERR = 2;
}

message GetOrganisationsRequest {}
message GetOrganisationsResponse {
  repeated OrganisationRef organisations = 1;
}

message GetProjectsRequest {
  oneof query {
    OrganisationRef organisation = 1;
  }
}
message GetProjectsResponse {
  repeated string projects = 1;
}



message GetReleasesByActorRequest {
  string actor_id = 1;        // user_id or app_id
  string actor_type = 2;      // "user" or "app"
  int32 page_size = 3;
  string page_token = 4;
}

message GetReleasesByActorResponse {
  repeated ReleaseIntentSummary releases = 1;
  string next_page_token = 2;
}

message ReleaseIntentSummary {
  string release_intent_id = 1;
  string artifact_id = 2;
  Project project = 3;
  repeated ReleaseDestinationStatus destinations = 4;
  string created_at = 5;
}

message ReleaseDestinationStatus {
  string destination = 1;
  string environment = 2;
  string status = 3;
}

message GetDestinationStatesRequest {
  string organisation = 1;
  optional string project = 2;
}

message GetDestinationStatesResponse {
  repeated DestinationState destinations = 1;
}

message DestinationState {
  string destination_id = 1;
  string destination_name = 2;
  string environment = 3;
  optional string release_id = 4;
  optional string artifact_id = 5;
  optional string status = 6;
  optional string error_message = 7;
  optional string queued_at = 8;
  optional string completed_at = 9;
  optional int32 queue_position = 10;
}

service ReleaseService {
  rpc AnnotateRelease(AnnotateReleaseRequest) returns (AnnotateReleaseResponse);
  rpc Release(ReleaseRequest) returns (ReleaseResponse);
  rpc WaitRelease(WaitReleaseRequest) returns (stream WaitReleaseEvent);

  rpc GetArtifactBySlug(GetArtifactBySlugRequest) returns (GetArtifactBySlugResponse);
  rpc GetArtifactsByProject(GetArtifactsByProjectRequest) returns (GetArtifactsByProjectResponse);
  rpc GetReleasesByActor(GetReleasesByActorRequest) returns (GetReleasesByActorResponse);
  rpc GetOrganisations(GetOrganisationsRequest) returns (GetOrganisationsResponse);
  rpc GetProjects(GetProjectsRequest) returns (GetProjectsResponse);
  rpc GetDestinationStates(GetDestinationStatesRequest) returns (GetDestinationStatesResponse);
}

message Source {
  optional string user = 1;
  optional string email = 2;
  optional string source_type = 3;
  optional string run_url = 4;
}

message ArtifactContext {
  string title = 1;
  optional string description = 2;
  optional string web = 3;
  optional string pr = 4;
}

message Artifact {
  string id = 1;
  string artifact_id = 2;
  string slug = 3;
  map<string, string> metadata = 4;
  Source source = 5;
  ArtifactContext context = 6;
  Project project = 7;
  repeated ArtifactDestination destinations = 8;
  string created_at = 9;
}

message ArtifactDestination {
  string name = 1;
  string environment = 2;
  string type_organisation = 3;
  string type_name = 4;
  uint64 type_version = 5;
  string status = 6;
}

message Project {
  string organisation = 1;
  string project = 2;
}

message Ref {
  string commit_sha = 1;
  optional string branch = 2;
  optional string commit_message = 3;
  optional string version = 4;
  optional string repo_url = 5;
}

message OrganisationRef {
  string organisation = 1;
}
