// 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.gkehub.servicemesh.v1alpha;

import "google/api/field_behavior.proto";
import "google/protobuf/struct.proto";

option csharp_namespace = "Google.Cloud.GkeHub.ServiceMesh.V1Alpha";
option go_package = "cloud.google.com/go/gkehub/servicemesh/apiv1alpha/servicemeshpb;servicemeshpb";
option java_multiple_files = true;
option java_outer_classname = "ServiceMeshProto";
option java_package = "com.google.cloud.gkehub.servicemesh.v1alpha";
option php_namespace = "Google\\Cloud\\GkeHub\\ServiceMesh\\V1alpha";
option ruby_package = "Google::Cloud::GkeHub::ServiceMesh::V1alpha";

// **Service Mesh**: State for the whole Hub, as analyzed by the Service Mesh
// Hub Controller.
message FeatureState {
  // Output only. Results of running Service Mesh analyzers.
  repeated AnalysisMessage analysis_messages = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// **Service Mesh**: State for a single Membership, as analyzed by the Service
// Mesh Hub Controller.
message MembershipState {
  // Output only. Results of running Service Mesh analyzers.
  repeated AnalysisMessage analysis_messages = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// AnalysisMessageBase describes some common information that is
// needed for all messages.
message AnalysisMessageBase {
  // A unique identifier for the type of message. Display_name is intended to be
  // human-readable, code is intended to be machine readable. There should be a
  // one-to-one mapping between display_name and code. (i.e. do not re-use
  // display_names or codes between message types.)
  // See istio.analysis.v1alpha1.AnalysisMessageBase.Type
  message Type {
    // A human-readable name for the message type. e.g. "InternalError",
    // "PodMissingProxy". This should be the same for all messages of the same
    // type. (This corresponds to the `name` field in open-source Istio.)
    string display_name = 1;

    // A 7 character code matching `^IST[0-9]{4}$` or `^ASM[0-9]{4}$`, intended
    // to uniquely identify the message type. (e.g. "IST0001" is mapped to the
    // "InternalError" message type.)
    string code = 2;
  }

  // The values here are chosen so that more severe messages get sorted higher,
  // as well as leaving space in between to add more later
  // See istio.analysis.v1alpha1.AnalysisMessageBase.Level
  enum Level {
    // Illegal. Same istio.analysis.v1alpha1.AnalysisMessageBase.Level.UNKNOWN.
    LEVEL_UNSPECIFIED = 0;

    // ERROR represents a misconfiguration that must be fixed.
    ERROR = 3;

    // WARNING represents a misconfiguration that should be fixed.
    WARNING = 8;

    // INFO represents an informational finding.
    INFO = 12;
  }

  // Represents the specific type of a message.
  Type type = 1;

  // Represents how severe a message is.
  Level level = 2;

  // A url pointing to the Service Mesh or Istio documentation for this specific
  // error type.
  string documentation_url = 3;
}

// AnalysisMessage is a single message produced by an analyzer, and
// it used to communicate to the end user about the state of their Service
// Mesh configuration.
message AnalysisMessage {
  // Details common to all types of Istio and ServiceMesh analysis messages.
  AnalysisMessageBase message_base = 1;

  // A human readable description of what the error means. It is suitable for
  // non-internationalize display purposes.
  string description = 2;

  // A list of strings specifying the resource identifiers that were the cause
  // of message generation.
  // A "path" here may be:
  // * MEMBERSHIP_ID if the cause is a specific member cluster
  // * MEMBERSHIP_ID/(NAMESPACE\/)?RESOURCETYPE/NAME if the cause is a resource
  // in a cluster
  repeated string resource_paths = 3;

  // A UI can combine these args with a template (based on message_base.type)
  // to produce an internationalized message.
  google.protobuf.Struct args = 4;
}
