// Copyright 2025 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.cloud.networkservices.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.NetworkServices.V1";
option go_package = "cloud.google.com/go/networkservices/apiv1/networkservicespb;networkservicespb";
option java_multiple_files = true;
option java_outer_classname = "ServiceLbPolicyProto";
option java_package = "com.google.cloud.networkservices.v1";
option php_namespace = "Google\\Cloud\\NetworkServices\\V1";
option ruby_package = "Google::Cloud::NetworkServices::V1";

// ServiceLbPolicy holds global load balancing and traffic distribution
// configuration that can be applied to a BackendService.
message ServiceLbPolicy {
  option (google.api.resource) = {
    type: "networkservices.googleapis.com/ServiceLbPolicy"
    pattern: "projects/{project}/locations/{location}/serviceLbPolicies/{service_lb_policy}"
  };

  // Option to specify if an unhealthy IG/NEG should be considered for global
  // load balancing and traffic routing.
  message AutoCapacityDrain {
    // Optional. If set to 'True', an unhealthy IG/NEG will be set as drained.
    // - An IG/NEG is considered unhealthy if less than 25% of the
    // instances/endpoints in the IG/NEG are healthy.
    // - This option will never result in draining more than 50% of the
    // configured IGs/NEGs for the Backend Service.
    bool enable = 1 [(google.api.field_behavior) = OPTIONAL];
  }

  // Option to specify health based failover behavior.
  // This is not related to Network load balancer FailoverPolicy.
  message FailoverConfig {
    // Optional. The percentage threshold that a load balancer will begin to
    // send traffic to failover backends. If the percentage of endpoints in a
    // MIG/NEG is smaller than this value, traffic would be sent to failover
    // backends if possible. This field should be set to a value between 1
    // and 99. The default value is 50 for Global external HTTP(S) load balancer
    // (classic) and Proxyless service mesh, and 70 for others.
    int32 failover_health_threshold = 1
        [(google.api.field_behavior) = OPTIONAL];
  }

  // Configuration to provide isolation support for the associated Backend
  // Service.
  message IsolationConfig {
    // Optional. The isolation granularity of the load balancer.
    IsolationGranularity isolation_granularity = 1
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. The isolation mode of the load balancer.
    IsolationMode isolation_mode = 2 [(google.api.field_behavior) = OPTIONAL];
  }

  // The global load balancing algorithm to be used.
  enum LoadBalancingAlgorithm {
    // The type of the loadbalancing algorithm is unspecified.
    LOAD_BALANCING_ALGORITHM_UNSPECIFIED = 0;

    // Balance traffic across all backends across the world proportionally based
    // on capacity.
    SPRAY_TO_WORLD = 3;

    // Direct traffic to the nearest region with endpoints and capacity before
    // spilling over to other regions and spread the traffic from each client to
    // all the MIGs/NEGs in a region.
    SPRAY_TO_REGION = 4;

    // Direct traffic to the nearest region with endpoints and capacity before
    // spilling over to other regions. All MIGs/NEGs within a region are evenly
    // loaded but each client might not spread the traffic to all the MIGs/NEGs
    // in the region.
    WATERFALL_BY_REGION = 5;

    // Attempt to keep traffic in a single zone closest to the client, before
    // spilling over to other zones.
    WATERFALL_BY_ZONE = 6;
  }

  // The granularity of this isolation restriction.
  enum IsolationGranularity {
    // No isolation is configured for the backend service. Traffic can overflow
    // based on the load balancing algorithm.
    ISOLATION_GRANULARITY_UNSPECIFIED = 0;

    // Traffic for this service will be isolated at the cloud region level.
    REGION = 1;
  }

  // The mode of this isolation restriction, defining whether clients in a given
  // region are allowed to reach out to another region.
  enum IsolationMode {
    // No isolation mode is configured for the backend service.
    ISOLATION_MODE_UNSPECIFIED = 0;

    // Traffic will be sent to the nearest region.
    NEAREST = 1;

    // Traffic will fail if no serving backends are available in the same region
    // as the load balancer.
    STRICT = 2;
  }

  // Identifier. Name of the ServiceLbPolicy resource. It matches pattern
  // `projects/{project}/locations/{location}/serviceLbPolicies/{service_lb_policy_name}`.
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Output only. The timestamp when this resource was created.
  google.protobuf.Timestamp create_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The timestamp when this resource was last updated.
  google.protobuf.Timestamp update_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Set of label tags associated with the ServiceLbPolicy resource.
  map<string, string> labels = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A free-text description of the resource. Max length 1024
  // characters.
  string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The type of load balancing algorithm to be used. The default
  // behavior is WATERFALL_BY_REGION.
  LoadBalancingAlgorithm load_balancing_algorithm = 6
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Configuration to automatically move traffic away for unhealthy
  // IG/NEG for the associated Backend Service.
  AutoCapacityDrain auto_capacity_drain = 8
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Configuration related to health based failover.
  FailoverConfig failover_config = 10 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Configuration to provide isolation support for the associated
  // Backend Service.
  IsolationConfig isolation_config = 11
      [(google.api.field_behavior) = OPTIONAL];
}

// Request used with the ListServiceLbPolicies method.
message ListServiceLbPoliciesRequest {
  // Required. The project and location from which the ServiceLbPolicies should
  // be listed, specified in the format
  // `projects/{project}/locations/{location}`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "networkservices.googleapis.com/ServiceLbPolicy"
    }
  ];

  // Maximum number of ServiceLbPolicies to return per call.
  int32 page_size = 2;

  // The value returned by the last `ListServiceLbPoliciesResponse`
  // Indicates that this is a continuation of a prior `ListRouters` call,
  // and that the system should return the next page of data.
  string page_token = 3;
}

// Response returned by the ListServiceLbPolicies method.
message ListServiceLbPoliciesResponse {
  // List of ServiceLbPolicy resources.
  repeated ServiceLbPolicy service_lb_policies = 1;

  // If there might be more results than those appearing in this response, then
  // `next_page_token` is included. To get the next set of results, call this
  // method again using the value of `next_page_token` as `page_token`.
  string next_page_token = 2;

  // Unreachable resources. Populated when the request attempts to list all
  // resources across all supported locations, while some locations are
  // temporarily unavailable.
  repeated string unreachable = 3;
}

// Request used by the GetServiceLbPolicy method.
message GetServiceLbPolicyRequest {
  // Required. A name of the ServiceLbPolicy to get. Must be in the format
  // `projects/{project}/locations/{location}/serviceLbPolicies/*`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkservices.googleapis.com/ServiceLbPolicy"
    }
  ];
}

// Request used by the ServiceLbPolicy method.
message CreateServiceLbPolicyRequest {
  // Required. The parent resource of the ServiceLbPolicy. Must be in the
  // format `projects/{project}/locations/{location}`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "networkservices.googleapis.com/ServiceLbPolicy"
    }
  ];

  // Required. Short name of the ServiceLbPolicy resource to be created.
  // E.g. for resource name
  // `projects/{project}/locations/{location}/serviceLbPolicies/{service_lb_policy_name}`.
  // the id is value of {service_lb_policy_name}
  string service_lb_policy_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. ServiceLbPolicy resource to be created.
  ServiceLbPolicy service_lb_policy = 3
      [(google.api.field_behavior) = REQUIRED];
}

// Request used by the UpdateServiceLbPolicy method.
message UpdateServiceLbPolicyRequest {
  // Optional. Field mask is used to specify the fields to be overwritten in the
  // ServiceLbPolicy resource by the update.
  // The fields specified in the update_mask are relative to the resource, not
  // the full request. A field will be overwritten if it is in the mask. If the
  // user does not provide a mask then all fields will be overwritten.
  google.protobuf.FieldMask update_mask = 1
      [(google.api.field_behavior) = OPTIONAL];

  // Required. Updated ServiceLbPolicy resource.
  ServiceLbPolicy service_lb_policy = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Request used by the DeleteServiceLbPolicy method.
message DeleteServiceLbPolicyRequest {
  // Required. A name of the ServiceLbPolicy to delete. Must be in the format
  // `projects/{project}/locations/{location}/serviceLbPolicies/*`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkservices.googleapis.com/ServiceLbPolicy"
    }
  ];
}
