// 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.chronicle.v1;

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

option csharp_namespace = "Google.Cloud.Chronicle.V1";
option go_package = "cloud.google.com/go/chronicle/apiv1/chroniclepb;chroniclepb";
option java_multiple_files = true;
option java_outer_classname = "EntityProto";
option java_package = "google.cloud.chronicle.v1";
option php_namespace = "Google\\Cloud\\Chronicle\\V1";
option ruby_package = "Google::Cloud::Chronicle::V1";

// EntityService contains apis for finding entities.
service EntityService {
  option (google.api.default_host) = "chronicle.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Gets watchlist details for the given watchlist ID.
  rpc GetWatchlist(GetWatchlistRequest) returns (Watchlist) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/instances/*/watchlists/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists all watchlists for the given instance.
  rpc ListWatchlists(ListWatchlistsRequest) returns (ListWatchlistsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*/instances/*}/watchlists"
    };
    option (google.api.method_signature) = "parent";
  }

  // Creates a watchlist for the given instance.
  // Note that there can be at most 200 watchlists per instance.
  rpc CreateWatchlist(CreateWatchlistRequest) returns (Watchlist) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*/instances/*}/watchlists"
      body: "watchlist"
    };
    option (google.api.method_signature) = "parent,watchlist,watchlist_id";
  }

  // Updates the watchlist for the given instance.
  rpc UpdateWatchlist(UpdateWatchlistRequest) returns (Watchlist) {
    option (google.api.http) = {
      patch: "/v1/{watchlist.name=projects/*/locations/*/instances/*/watchlists/*}"
      body: "watchlist"
    };
    option (google.api.method_signature) = "watchlist,update_mask";
  }

  // Deletes the watchlist for the given instance.
  rpc DeleteWatchlist(DeleteWatchlistRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/instances/*/watchlists/*}"
    };
    option (google.api.method_signature) = "name,force";
  }
}

// A watchlist is a list of entities that allows for bulk operations over the
// included entities.
message Watchlist {
  option (google.api.resource) = {
    type: "chronicle.googleapis.com/Watchlist"
    pattern: "projects/{project}/locations/{location}/instances/{instance}/watchlists/{watchlist}"
    plural: "watchlists"
    singular: "watchlist"
  };

  // Mechanism to populate entities in the watchlist.
  message EntityPopulationMechanism {
    // Entities are added manually.
    message Manual {}

    // Ways to populate entities in watchlist.
    // Currently, only manual is supported.
    oneof mechanism {
      // Optional. Entities are added manually.
      Manual manual = 1 [(google.api.field_behavior) = OPTIONAL];
    }
  }

  // Count of different types of entities in the watchlist.
  message EntityCount {
    // Output only. Count of user type entities in the watchlist.
    int32 user = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Count of asset type entities in the watchlist.
    int32 asset = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Identifier. Resource name of the watchlist.
  // Format:
  // `projects/{project}/locations/{location}/instances/{instance}/watchlists/{watchlist}`
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Required. Display name of the watchlist.
  // Note that it must be at least one character and less than 63 characters
  // (https://google.aip.dev/148).
  string display_name = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. Description of the watchlist.
  string description = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Weight applied to the risk score for entities
  // in this watchlist.
  // The default is 1.0 if it is not specified.
  float multiplying_factor = 5 [(google.api.field_behavior) = OPTIONAL];

  // Required. Mechanism to populate entities in the watchlist.
  EntityPopulationMechanism entity_population_mechanism = 6
      [(google.api.field_behavior) = REQUIRED];

  // Output only. Entity count in the watchlist.
  EntityCount entity_count = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Time the watchlist was created.
  google.protobuf.Timestamp create_time = 8
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Time the watchlist was last updated.
  google.protobuf.Timestamp update_time = 9
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. User preferences for watchlist configuration.
  WatchlistUserPreferences watchlist_user_preferences = 10
      [(google.api.field_behavior) = OPTIONAL];
}

// A collection of user preferences for watchlist UI configuration.
message WatchlistUserPreferences {
  // Optional. Whether the watchlist is pinned on the dashboard.
  bool pinned = 1 [(google.api.field_behavior) = OPTIONAL];
}

// Request message for getting a watchlist.
message GetWatchlistRequest {
  // Required. The parent, which owns this collection of watchlists.
  // The name of the watchlist to retrieve.
  // Format:
  // `projects/{project}/locations/{location}/instances/{instance}/watchlists/{watchlist}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "chronicle.googleapis.com/Watchlist"
    }
  ];
}

// Request message for listing watchlists.
message ListWatchlistsRequest {
  // Required. The parent, which owns this collection of watchlists.
  // Format: `projects/{project}/locations/{location}/instances/{instance}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "chronicle.googleapis.com/Watchlist"
    }
  ];

  // Optional. The maximum number of watchlists to return.
  // The service may return fewer than this value.
  // If unspecified, at most 200 watchlists will be returned.
  // The maximum value is 200; values above 200 will be coerced to 200.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A page token, received from a previous `ListWatchlists` call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to
  // `ListWatchlists` must match the call that provided the page
  // token.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Which watchlist to return in aip.dev/160 form.
  // Currently, only the following filters are supported:
  // - `watchlist_user_preferences.pinned=true`
  // - `has_entity([ENTITY_INDICATOR],[ENTITY_TYPE])`
  // - `has_entity([ENTITY_INDICATOR],[ENTITY_TYPE],[NAMESPACE])`
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for listing watchlists.
message ListWatchlistsResponse {
  // Optional. The watchlists from the specified instance.
  repeated Watchlist watchlists = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A token, which can be sent as `page_token` to retrieve the next
  // page. If this field is omitted, there are no subsequent pages.
  string next_page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request message for creating watchlist.
message CreateWatchlistRequest {
  // Required. The parent resource where this watchlist will be created.
  // Format: `projects/{project}/locations/{location}/instances/{instance}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "chronicle.googleapis.com/Watchlist"
    }
  ];

  // Optional. The ID to use for the watchlist,
  // which will become the final component of the watchlist's resource name.
  //
  // This value should be 4-63 characters, and valid characters
  // are /[a-z][0-9]-/.
  string watchlist_id = 2 [(google.api.field_behavior) = OPTIONAL];

  // Required. The watchlist to create.
  Watchlist watchlist = 3 [(google.api.field_behavior) = REQUIRED];
}

// Request message for updating watchlist.
message UpdateWatchlistRequest {
  // Required. The watchlist to update.
  //
  // The watchlist's `name` field is used to identify the watchlist to update.
  // Format:
  // `projects/{project}/locations/{location}/instances/{instance}/watchlists/{watchlist}`
  Watchlist watchlist = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The list of fields to update.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = OPTIONAL];
}

// Request message for deleting watchlist.
message DeleteWatchlistRequest {
  // Required. The name of the watchlist to delete.
  // Format:
  // `projects/{project}/locations/{location}/instances/{instance}/watchlists/{watchlist}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "chronicle.googleapis.com/Watchlist"
    }
  ];

  // Optional. If set to true, any entities under this watchlist will also be
  // deleted. (Otherwise, the request will only work if the watchlist has no
  // entities.)
  bool force = 2 [(google.api.field_behavior) = OPTIONAL];
}
