// Copyright 2026 Google LLC
//
// 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.

syntax = "proto3";

package google.chromeos.moblab.v1beta1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/api/routing.proto";
import "google/chromeos/moblab/v1beta1/resources.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";

option go_package = "google.golang.org/genproto/googleapis/chromeos/moblab/v1beta1;moblab";
option java_multiple_files = true;
option java_outer_classname = "BuildServiceProto";
option java_package = "com.google.chromeos.moblab.v1beta1";
option optimize_for = SPEED;

// Manages Chrome OS build services.
service BuildService {
  option (google.api.default_host) = "chromeosmoblab.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/moblabapi";

  // Lists all build targets that a user has access to.
  rpc ListBuildTargets(ListBuildTargetsRequest)
      returns (ListBuildTargetsResponse) {
    option (google.api.http) = {
      get: "/v1beta1/buildTargets"
    };
  }

  // Lists all models for the given build target.
  rpc ListModels(ListModelsRequest) returns (ListModelsResponse) {
    option (google.api.http) = {
      get: "/v1beta1/{parent=buildTargets/*}/models"
    };
    option (google.api.method_signature) = "parent";
  }

  // Lists all builds for the given build target and model in descending order
  // for the milestones and build versions.
  rpc ListBuilds(ListBuildsRequest) returns (ListBuildsResponse) {
    option (google.api.http) = {
      get: "/v1beta1/{parent=buildTargets/*/models/*}/builds"
    };
    option (google.api.method_signature) = "parent";
  }

  // Checks the stage status for a given build artifact in a partner Google
  // Cloud Storage bucket.
  rpc CheckBuildStageStatus(CheckBuildStageStatusRequest)
      returns (CheckBuildStageStatusResponse) {
    option (google.api.http) = {
      get: "/v1beta1/{name=buildTargets/*/models/*/builds/*/artifacts/*}:check"
    };
    option (google.api.method_signature) = "name";
  }

  // Stages a given build artifact from a internal Google Cloud Storage bucket
  // to a partner Google Cloud Storage bucket. The stage will be skipped if all
  // the objects in the partner bucket are the same as in the internal bucket.
  // Operation
  // <response:[StageBuildResponse][google.chromeos.moblab.v1beta1.StageBuildResponse],
  //            metadata:
  //           [StageBuildMetadata][google.chromeos.moblab.v1beta1.StageBuildMetadata]>
  rpc StageBuild(StageBuildRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1beta1/{name=buildTargets/*/models/*/builds/*/artifacts/*}:stage"
      body: "*"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "StageBuildResponse"
      metadata_type: "StageBuildMetadata"
    };
  }

  // Finds the most stable build for the given build target. The definition of
  // the most stable build is determined by evaluating the following rule in
  // order until one is true. If none are true, then there is no stable build
  // and it will return an empty response.
  //
  // Evaluation rules:
  //   1. Stable channel build with label “Live”
  //   2. Beta channel build with label “Live”
  //   3. Dev channel build with label “Live”
  //   4. Most recent stable channel build with build status Pass
  //   5. Most recent beta channel build with build status Pass
  //   6. Most recent dev channel build with build status Pass
  rpc FindMostStableBuild(FindMostStableBuildRequest)
      returns (FindMostStableBuildResponse) {
    option (google.api.http) = {
      get: "/v1beta1/{build_target=buildTargets/*}:findMostStableBuild"
      additional_bindings {
        get: "/v1beta1/{model=buildTargets/*/models/*}:findMostStableBuild"
      }
    };
    option (google.api.routing) = {
      routing_parameters {
        field: "build_target"
        path_template: "{build_target=buildTargets/*}"
      }
      routing_parameters {
        field: "model"
        path_template: "{model=buildTargets/*/models/*}"
      }
    };
    option (google.api.method_signature) = "build_target";
  }
}

// Request message for finding the most stable build.
// -- NEXT_TAG: 3 --
message FindMostStableBuildRequest {
  // Optional. The full resource name of the build target.
  // For example,
  // 'buildTargets/octopus'.
  string build_target = 1 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.resource_reference) = {
      type: "chromeosmoblab.googleapis.com/BuildTarget"
    }
  ];

  // Optional. The full resource name of the build target or model.
  // For example,
  // 'buildTargets/octopus/models/bobba'.
  string model = 2 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.resource_reference) = {
      type: "chromeosmoblab.googleapis.com/Model"
    }
  ];
}

// Response message for finding the most stable build.
// -- NEXT_TAG: 2 --
message FindMostStableBuildResponse {
  // The most stable build.
  Build build = 1;
}

// Request message for listing build targets.
// -- NEXT_TAG: 4 --
message ListBuildTargetsRequest {
  // Optional. The number of build targets to return in a page.
  int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A page token, received from a previous `ListBuildTargets` call.
  // Provide this to retrieve the subsequent page.
  string page_token = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Filter that specifies value constraints of fields. For example,
  // the filter can be set as "filter='model=modelName'" to only select build
  // targets associated with the given model.
  string filter = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for listing build targets.
// -- NEXT_TAG: 4 --
message ListBuildTargetsResponse {
  // The list of build targets.
  repeated BuildTarget build_targets = 1;

  // Token to retrieve the next page of build targets. If this field is omitted,
  // there are no subsequent pages.
  string next_page_token = 2;

  // Total number of build targets.
  int32 total_size = 3;
}

// Request message for listing models.
// -- NEXT_TAG: 4 --
message ListModelsRequest {
  // Required. The full resource name of build target.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "chromeosmoblab.googleapis.com/BuildTarget"
    }
  ];

  // Optional. The number of models to return in a page.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A page token, received from a previous `ListModels` call. Provide
  // this to retrieve the subsequent page.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for listing models.
// -- NEXT_TAG: 4 --
message ListModelsResponse {
  // The list of models.
  repeated Model models = 1;

  // Token to retrieve the next page of models. If this field is omitted, there
  // are no subsequent pages.
  string next_page_token = 2;

  // Total number of models.
  int32 total_size = 3;
}

// Request message for listing builds.
// -- NEXT_TAG: 7 --
message ListBuildsRequest {
  // Required. The full resource name of the model. The model id is the same as
  // the build target id for non-unified builds.
  // For example,
  // 'buildTargets/octopus/models/bobba'.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "chromeosmoblab.googleapis.com/Model"
    }
  ];

  // Optional. The number of builds to return in a page.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A page token, received from a previous `ListBuilds` call. Provide
  // this to retrieve the subsequent page.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Filter that specifies value constraints of fields. For example,
  // the filter can be set as "filter='milestone=milestones/80'" to only select
  // builds in milestone 80.
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Read mask that specifies which Build fields to return. If empty,
  // all Build fields will be returned. Valid fields: name, milestone,
  // build_version. For example, if the read_mask is set as
  // "read_mask='milestone'", the ListBuilds will return a list of Builds object
  // with only the milestone field.
  google.protobuf.FieldMask read_mask = 5
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The operation that groups by all the Build fields specified in
  // the read mask. The group_by field should be the same as the read_mask field
  // in convention of SQL.
  google.protobuf.FieldMask group_by = 6
      [(google.api.field_behavior) = OPTIONAL];
}

// Response message for listing builds.
// -- NEXT_TAG: 4 --
message ListBuildsResponse {
  // The list of builds.
  repeated Build builds = 1;

  // Token to retrieve the next page of builds. If this field is omitted, there
  // are no subsequent pages.
  string next_page_token = 2;

  // Total number of builds.
  int32 total_size = 3;
}

// Request message for checking if the build artifact is staged.
// -- NEXT_TAG: 3 --
message CheckBuildStageStatusRequest {
  // Required. The full resource name of the build artifact.
  // For example,
  // 'buildTargets/octopus/models/bobba/builds/12607.6.0/artifacts/chromeos-moblab-peng-staging'.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "chromeosmoblab.googleapis.com/BuildArtifact"
    }
  ];

  // Optional. Filter that specifies value constraints of fields. For example,
  // the filter can be set as "filter='type=release'" to only check the release
  // builds.
  string filter = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for checking the stage status of a build artifact.
// -- NEXT_TAG: 5 --
message CheckBuildStageStatusResponse {
  // The status to represent if the build is staged or not.
  bool is_build_staged = 1;

  // The staged build artifact in the destination bucket.
  BuildArtifact staged_build_artifact = 2;

  // The source build artifact in the source bucket.
  BuildArtifact source_build_artifact = 3;

  // Optional. The cloud build if the build id is provided.
  CloudBuild cloud_build = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Request message for staging a build artifact.
// -- NEXT_TAG: 6 --
message StageBuildRequest {
  // Required. The full resource name of the build artifact.
  // For example,
  // 'buildTargets/octopus/models/bobba/builds/12607.6.0/artifacts/chromeos-moblab-peng-staging'.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "chromeosmoblab.googleapis.com/BuildArtifact"
    }
  ];

  // Optional. Filter that specifies value constraints of fields. For example,
  // the filter can be set as "filter='type=release'" to only check the release
  // builds.
  string filter = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The source location of the artifact, defaults to
  // `chromeos-image-archive` if missing.
  string source_bucket_id = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The branch directory in the source_bucket_id where the artifact
  // is located, such as `firmware-ec-R143-16463.2.B`. If unspecified, the build
  // will be found in goldeneye by version number.
  string branch = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The name of the artifact to stage, such as
  // `karis.EC.16463.2.6.tar.bz2` or `rex/firmware_from_source.tar.bz2` If
  // unspecified, the default artifacts will be staged. This only makes sense
  // for firmware artifacts.
  string artifact = 5 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for staging a build artifact.
// -- NEXT_TAG: 3 --
message StageBuildResponse {
  // The staged build in the destination bucket.
  BuildArtifact staged_build_artifact = 1;

  // The cloud build id of the build artifacts.
  CloudBuild cloud_build = 2 [deprecated = true];
}

// Metadata message for staging a build artifact.
// -- NEXT_TAG: 5 --
message StageBuildMetadata {
  // Approximate percentage of progress, e.g. "50" means 50%.
  float progress_percent = 1;

  // Build stage start time.
  google.protobuf.Timestamp start_time = 2;

  // Build stage end time.
  google.protobuf.Timestamp end_time = 3;

  // The cloud build of the build artifacts.
  CloudBuild cloud_build = 4;
}
