// TelemetryService -- public CRUD surface for per-user OTel export
// configurations (sink URL + protocol + auth) the management plane
// forwards traces/metrics/logs to.
//
// Underlying storage is the existing `telemetry_configs` table the
// admin.v1 AdminService already manages. This file promotes those RPCs
// onto the proto-driven IA surface; the handler in
// `svc/internal/telemetrysvc/` is a thin shim that delegates to the
// same TelemetryConfigRepository -- no parallel SQL.
//
// Scoping model: telemetry config now has two scopes that share the same
// (customer, project) address:
//   - PER-USER config (Create/List/Get/Update/Delete) is account-tier:
//     every member manages their OWN config, keyed by the authenticated
//     caller's user_id.
//   - PROJECT-level config (SetProjectTelemetryConfig /
//     GetProjectTelemetryConfig) is project_owner-tier: the project owner
//     sets a shared default for the project.
// At telemetry-emit time the resolver PREFERS the user's own config and
// falls back to the project-level config (see telemetrysvc.ResolveEffective
// and the consumer wiring note there).
//
// Storage note: the underlying `telemetry_configs` table is user-keyed
// (one row per (user_id, telemetry_type)). Project-level rows reuse that
// table under a deterministic synthetic owner key
// ("proj::<customer>::<project>") so no schema migration to the admin
// telemetry table is required; the public surface and the override
// resolution live in the telemetrysvc shim.
syntax = "proto3";

package tars.telemetry.v1;

import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";
import "tars/auth/v1/auth_options.proto";
import "tars/cli/v1/cli.proto";
import "tars/docs/v1/docs.proto";

option go_package = "github.com/tetrateio/fraser/api/tars/telemetry/v1;telemetryv1";

// TelemetryService manages OTel export configurations (one per
// telemetry_type per user).
service TelemetryService {
  // CreateTelemetryConfig creates a new OTel export configuration.
  rpc CreateTelemetryConfig(CreateTelemetryConfigRequest) returns (TelemetryConfig) {
    option (tars.docs.v1.title) = "Create a telemetry export config";
    option (tars.docs.v1.group) = "Telemetry";
    option (google.api.http) = {
      post: "/v1/customers/{customer_id}/projects/{project_id}/telemetry"
      body: "*"
    };
    option (tars.auth.v1.auth) = {
      auth_types: [
        AUTH_TYPE_USER_TOKEN,
        AUTH_TYPE_API_KEY
      ]
    };
    option (tars.cli.v1.command) = {
      path: [
        "telemetry",
        "create"
      ]
    };
  }

  // ListTelemetryConfigs lists every configuration owned by the caller
  // within the (customer, project) scope.
  rpc ListTelemetryConfigs(ListTelemetryConfigsRequest) returns (ListTelemetryConfigsResponse) {
    option (tars.docs.v1.title) = "List telemetry export configs";
    option (tars.docs.v1.group) = "Telemetry";
    option (google.api.http) = {get: "/v1/customers/{customer_id}/projects/{project_id}/telemetry"};
    option idempotency_level = NO_SIDE_EFFECTS;
    option (tars.auth.v1.auth) = {
      auth_types: [
        AUTH_TYPE_USER_TOKEN,
        AUTH_TYPE_API_KEY
      ]
    };
    option (tars.cli.v1.command) = {
      path: [
        "telemetry",
        "list"
      ]
    };
  }

  // GetTelemetryConfig returns a single configuration by id.
  rpc GetTelemetryConfig(GetTelemetryConfigRequest) returns (TelemetryConfig) {
    option (tars.docs.v1.title) = "Get a telemetry export config";
    option (tars.docs.v1.group) = "Telemetry";
    option (google.api.http) = {get: "/v1/customers/{customer_id}/projects/{project_id}/telemetry/{config_id}"};
    option idempotency_level = NO_SIDE_EFFECTS;
    option (tars.auth.v1.auth) = {
      auth_types: [
        AUTH_TYPE_USER_TOKEN,
        AUTH_TYPE_API_KEY
      ]
    };
    option (tars.cli.v1.command) = {
      path: [
        "telemetry",
        "get"
      ]
    };
  }

  // UpdateTelemetryConfig updates a configuration's mutable fields.
  rpc UpdateTelemetryConfig(UpdateTelemetryConfigRequest) returns (TelemetryConfig) {
    option (tars.docs.v1.title) = "Update a telemetry export config";
    option (tars.docs.v1.group) = "Telemetry";
    option (google.api.http) = {
      patch: "/v1/customers/{customer_id}/projects/{project_id}/telemetry/{config_id}"
      body: "*"
    };
    option (tars.auth.v1.auth) = {
      auth_types: [
        AUTH_TYPE_USER_TOKEN,
        AUTH_TYPE_API_KEY
      ]
    };
    option (tars.cli.v1.command) = {
      path: [
        "telemetry",
        "update"
      ]
    };
  }

  // DeleteTelemetryConfig removes a configuration.
  rpc DeleteTelemetryConfig(DeleteTelemetryConfigRequest) returns (google.protobuf.Empty) {
    option (tars.docs.v1.title) = "Delete a telemetry export config";
    option (tars.docs.v1.group) = "Telemetry";
    option (google.api.http) = {delete: "/v1/customers/{customer_id}/projects/{project_id}/telemetry/{config_id}"};
    option (tars.auth.v1.auth) = {
      auth_types: [
        AUTH_TYPE_USER_TOKEN,
        AUTH_TYPE_API_KEY
      ]
    };
    option (tars.cli.v1.command) = {
      path: [
        "telemetry",
        "delete"
      ]
    };
  }

  // SetProjectTelemetryConfig upserts the PROJECT-level telemetry export
  // config (the shared default applied to project members who have no
  // config of their own). Project-owner-tier: only the project's owner may
  // set it. A user's own per-user config OVERRIDES this at emit time.
  rpc SetProjectTelemetryConfig(SetProjectTelemetryConfigRequest) returns (TelemetryConfig) {
    option (tars.docs.v1.title) = "Set the project telemetry export config";
    option (tars.docs.v1.group) = "Telemetry";
    option (google.api.http) = {
      put: "/v1/customers/{customer_id}/projects/{project_id}/telemetry/project"
      body: "*"
    };
    option (tars.auth.v1.auth) = {
      auth_types: [
        AUTH_TYPE_USER_TOKEN,
        AUTH_TYPE_API_KEY
      ]
      scopes: ["project_owner"]
    };
    option (tars.cli.v1.command) = {
      path: [
        "telemetry",
        "set-project"
      ]
    };
  }

  // GetProjectTelemetryConfig returns the PROJECT-level telemetry config.
  // Project-owner-tier (the shared project default is managed by owners).
  rpc GetProjectTelemetryConfig(GetProjectTelemetryConfigRequest) returns (TelemetryConfig) {
    option (tars.docs.v1.title) = "Get the project telemetry export config";
    option (tars.docs.v1.group) = "Telemetry";
    option (google.api.http) = {get: "/v1/customers/{customer_id}/projects/{project_id}/telemetry/project"};
    option idempotency_level = NO_SIDE_EFFECTS;
    option (tars.auth.v1.auth) = {
      auth_types: [
        AUTH_TYPE_USER_TOKEN,
        AUTH_TYPE_API_KEY
      ]
      scopes: ["project_owner"]
    };
    option (tars.cli.v1.command) = {
      path: [
        "telemetry",
        "get-project"
      ]
    };
  }
}

// TelemetryConfig is one configuration row -- a sink + protocol +
// optional auth credentials.
message TelemetryConfig {
  // id is the server-assigned unique identifier for this config row.
  string id = 1;
  // user_id is the owning (authenticated) caller; the row key.
  string user_id = 2;
  // telemetry_type partitions sinks for traces, metrics, logs.
  string telemetry_type = 3;
  // sink_url is the destination OTLP endpoint.
  string sink_url = 4;
  // protocol is one of: grpc, http/json, http/protobuf.
  string protocol = 5;
  // auth_type is one of: none, bearer, basic, api_key.
  string auth_type = 6;
  // auth_value is a secret reference. Returned on Get / Create. Empty
  // on List (avoid leakage in bulk reads).
  string auth_value = 7;
  // api_key_header is the header name for api_key auth (defaults to
  // X-API-Key).
  string api_key_header = 8;
  // enabled indicates whether exports to this sink are active.
  bool enabled = 9;
  // last_checked_at is when the sink's reachability was last probed.
  google.protobuf.Timestamp last_checked_at = 10;
  // status is one of: connected, disconnected, error, testing.
  string status = 11;
  // created_at is when this config was first created.
  google.protobuf.Timestamp created_at = 12;
  // updated_at is when this config was last modified.
  google.protobuf.Timestamp updated_at = 13;
}

message CreateTelemetryConfigRequest {
  // customer_id scopes the request path; used for path-level validation.
  string customer_id = 1 [(google.api.field_behavior) = REQUIRED];
  // project_id scopes the request path; used for path-level validation.
  string project_id = 2 [(google.api.field_behavior) = REQUIRED];
  // telemetry_type partitions sinks; defaults to "traces" when empty.
  string telemetry_type = 3;
  // endpoint is the OTLP sink URL.
  string endpoint = 4 [(google.api.field_behavior) = REQUIRED];
  // protocol defaults to "http/protobuf" when empty.
  string protocol = 5;
  // auth_type defaults to "none" when empty.
  string auth_type = 6;
  // auth_value is the plaintext credential to encrypt at rest.
  string auth_value = 7;
  // api_key_header is the header name when auth_type is api_key.
  string api_key_header = 8;
  // headers is sugar for the CLI: any of these are appended as basic
  // headers on outbound exports. Currently advisory -- the backing
  // configuration carries auth_type + auth_value.
  map<string, string> headers = 9;
  // enabled toggles the configuration; defaults to true when unset.
  // Use the "yes"/"no"/"true"/"false" CLI form; absent is treated as
  // true.
  bool enabled = 10;
}

message ListTelemetryConfigsRequest {
  // customer_id scopes the request path; used for path-level validation.
  string customer_id = 1 [(google.api.field_behavior) = REQUIRED];
  // project_id scopes the request path; used for path-level validation.
  string project_id = 2 [(google.api.field_behavior) = REQUIRED];
  // Optional telemetry_type filter.
  string telemetry_type = 3;
  // enabled is a tri-state encoded as a string: "" (no filter), "true",
  // "false". Avoids `optional bool` because the CLI generator does not
  // yet emit pointer assignments.
  string enabled = 4;
}

message ListTelemetryConfigsResponse {
  // configs is the matching set of configs owned by the caller.
  repeated TelemetryConfig configs = 1;
  // total is the count of returned configs.
  int32 total = 2;
}

message GetTelemetryConfigRequest {
  // customer_id scopes the request path; used for path-level validation.
  string customer_id = 1 [(google.api.field_behavior) = REQUIRED];
  // project_id scopes the request path; used for path-level validation.
  string project_id = 2 [(google.api.field_behavior) = REQUIRED];
  // config_id is the id of the config to fetch.
  string config_id = 3 [(google.api.field_behavior) = REQUIRED];
}

message UpdateTelemetryConfigRequest {
  // customer_id scopes the request path; used for path-level validation.
  string customer_id = 1 [(google.api.field_behavior) = REQUIRED];
  // project_id scopes the request path; used for path-level validation.
  string project_id = 2 [(google.api.field_behavior) = REQUIRED];
  // config_id is the id of the config to update.
  string config_id = 3 [(google.api.field_behavior) = REQUIRED];
  // Empty string means "leave unchanged".
  string endpoint = 4;
  // protocol -- empty leaves unchanged; otherwise grpc, http/json, http/protobuf.
  string protocol = 5;
  // auth_type -- empty leaves unchanged; otherwise none, bearer, basic, api_key.
  string auth_type = 6;
  // auth_value -- new plaintext credential to encrypt; empty leaves unchanged.
  string auth_value = 7;
  // api_key_header -- header name for api_key auth; empty leaves unchanged.
  string api_key_header = 8;
  // enabled tri-state encoded as "" (unchanged), "true", "false".
  string enabled = 9;
  // status -- reported connection state; empty leaves unchanged.
  string status = 10;
}

message DeleteTelemetryConfigRequest {
  // customer_id scopes the request path; used for path-level validation.
  string customer_id = 1 [(google.api.field_behavior) = REQUIRED];
  // project_id scopes the request path; used for path-level validation.
  string project_id = 2 [(google.api.field_behavior) = REQUIRED];
  // config_id is the id of the config to delete.
  string config_id = 3 [(google.api.field_behavior) = REQUIRED];
}

message SetProjectTelemetryConfigRequest {
  // customer_id identifies the project's customer.
  string customer_id = 1 [(google.api.field_behavior) = REQUIRED];
  // project_id identifies the project whose shared config is being set.
  string project_id = 2 [(google.api.field_behavior) = REQUIRED];
  // telemetry_type partitions sinks; defaults to "traces" when empty.
  string telemetry_type = 3;
  // endpoint is the OTLP sink URL.
  string endpoint = 4 [(google.api.field_behavior) = REQUIRED];
  // protocol defaults to "http/protobuf" when empty.
  string protocol = 5;
  // auth_type defaults to "none" when empty.
  string auth_type = 6;
  // auth_value is the plaintext credential to encrypt at rest.
  string auth_value = 7;
  // api_key_header is the header name when auth_type is api_key.
  string api_key_header = 8;
  // enabled toggles the configuration; defaults to true when unset.
  bool enabled = 9;
}

message GetProjectTelemetryConfigRequest {
  // customer_id identifies the project's customer.
  string customer_id = 1 [(google.api.field_behavior) = REQUIRED];
  // project_id identifies the project whose shared config is requested.
  string project_id = 2 [(google.api.field_behavior) = REQUIRED];
  // telemetry_type partitions sinks; defaults to "traces" when empty.
  string telemetry_type = 3;
}
