// Copyright 2021 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/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 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. If any of objects has already
  // been copied, it will overwrite the previous objects. 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 rules 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"
    };
    option (google.api.method_signature) = "build_target";
  }
}

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

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

// Request message for listing build targets.
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];
}

// Response message for listing build targets.
message ListBuildTargetsResponse {
  // The list of build targets.
  repeated BuildTarget build_targets = 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 build targets.
  int32 total_size = 3;
}

// Request message for listing builds.
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.
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.
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.
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;
}

// Request message for staging a build artifact.
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];
}

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

// Metadata message for staging a build artifact.
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;
}
