// Copyright 2024 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.home.graph.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/home/graph/v1/device.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/struct.proto";

option go_package = "google.golang.org/genproto/googleapis/home/graph/v1;graph";
option java_outer_classname = "HomeGraphApiServiceProto";
option java_package = "com.google.home.graph.v1";
option php_namespace = "Google\\Home\\Graph\\V1";
option (google.api.resource_definition) = {
  type: "homegraph.googleapis.com/AgentUserPath"
  pattern: "agentUsers/{agent_user_path}"
};

// Google Home Graph API service. The Home Graph service provides support for
// accessing first-party and third-party devices stored in Google's Home Graph.
// The Home Graph database provides contextual data about the relationships
// between devices and the home.
//
// For more details, see the [Home Graph developer
// guide](https://developers.home.google.com/cloud-to-cloud/primer/home-graph).
service HomeGraphApiService {
  option (google.api.default_host) = "homegraph.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/homegraph";

  // Requests Google to send an `action.devices.SYNC`
  // [intent](https://developers.home.google.com/cloud-to-cloud/intents/sync)
  // to your smart home Action to update device metadata for the given user.
  //
  //
  // The third-party user's identity is passed via the `agent_user_id`
  // (see
  // [RequestSyncDevicesRequest][google.home.graph.v1.RequestSyncDevicesRequest]).
  // This request must be authorized using service account credentials from your
  // Actions console project.
  rpc RequestSyncDevices(RequestSyncDevicesRequest)
      returns (RequestSyncDevicesResponse) {
    option (google.api.http) = {
      post: "/v1/devices:requestSync"
      body: "*"
    };
    option (google.api.method_signature) = "agent_user_id";
  }

  // Reports device state and optionally sends device notifications.
  // Called by your smart home Action when the state of a third-party device
  // changes or you need to send a notification about the device.
  // See [Implement Report
  // State](https://developers.home.google.com/cloud-to-cloud/integration/report-state)
  // for more information.
  //
  // This method updates the device state according to its declared
  // [traits](https://developers.home.google.com/cloud-to-cloud/primer/device-types-and-traits).
  // Publishing a new state value outside of these traits will result in an
  // `INVALID_ARGUMENT` error response.
  //
  // The third-party user's identity is passed in via the `agent_user_id`
  // (see
  // [ReportStateAndNotificationRequest][google.home.graph.v1.ReportStateAndNotificationRequest]).
  // This request must be authorized using service account credentials from your
  // Actions console project.
  rpc ReportStateAndNotification(ReportStateAndNotificationRequest)
      returns (ReportStateAndNotificationResponse) {
    option (google.api.http) = {
      post: "/v1/devices:reportStateAndNotification"
      body: "*"
    };
    option (google.api.method_signature) =
        "request_id,event_id,agent_user_id,payload";
  }

  // Unlinks the given third-party user from your smart home Action.
  // All data related to this user will be deleted.
  //
  // For more details on how users link their accounts, see
  // [fulfillment and
  // authentication](https://developers.home.google.com/cloud-to-cloud/primer/fulfillment).
  //
  // The third-party user's identity is passed in via the `agent_user_id`
  // (see
  // [DeleteAgentUserRequest][google.home.graph.v1.DeleteAgentUserRequest]).
  // This request must be authorized using service account credentials from your
  // Actions console project.
  rpc DeleteAgentUser(DeleteAgentUserRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{agent_user_id=agentUsers/**}"
    };
    option (google.api.method_signature) = "request_id,agent_user_id";
  }

  // Gets the current states in Home Graph for the given set of the third-party
  // user's devices.
  //
  // The third-party user's identity is passed in via the `agent_user_id`
  // (see [QueryRequest][google.home.graph.v1.QueryRequest]).
  // This request must be authorized using service account credentials from your
  // Actions console project.
  rpc Query(QueryRequest) returns (QueryResponse) {
    option (google.api.http) = {
      post: "/v1/devices:query"
      body: "*"
    };
    option (google.api.method_signature) = "request_id,agent_user_id,inputs";
  }

  // Gets all the devices associated with the given third-party user.
  //
  // The third-party user's identity is passed in via the `agent_user_id`
  // (see [SyncRequest][google.home.graph.v1.SyncRequest]).
  // This request must be authorized using service account credentials from your
  // Actions console project.
  rpc Sync(SyncRequest) returns (SyncResponse) {
    option (google.api.http) = {
      post: "/v1/devices:sync"
      body: "*"
    };
    option (google.api.method_signature) = "request_id,agent_user_id";
  }
}

// Request type for the
// [`RequestSyncDevices`](#google.home.graph.v1.HomeGraphApiService.RequestSyncDevices)
// call.
message RequestSyncDevicesRequest {
  // Required. Third-party user ID.
  string agent_user_id = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. If set, the request will be added to a queue and a response will
  // be returned immediately. This enables concurrent requests for the given
  // `agent_user_id`, but the caller will not receive any error responses.
  bool async = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Response type for the
// [`RequestSyncDevices`](#google.home.graph.v1.HomeGraphApiService.RequestSyncDevices)
// call.
//
// Intentionally empty upon success. An HTTP response code is returned
// with more details upon failure.
message RequestSyncDevicesResponse {}

// Request type for the
// [`ReportStateAndNotification`](#google.home.graph.v1.HomeGraphApiService.ReportStateAndNotification)
// call. It may include states, notifications, or both. States and notifications
// are defined per `device_id` (for example, "123" and "456" in the following
// example).
//
// Example:
//
// ```json
// {
//   "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
//   "agentUserId": "1234",
//   "payload": {
//     "devices": {
//       "states": {
//         "123": {
//           "on": true
//         },
//         "456": {
//           "on": true,
//           "brightness": 10
//         }
//       },
//     }
//   }
// }
// ```
message ReportStateAndNotificationRequest {
  // Request ID used for debugging.
  string request_id = 1;

  // Unique identifier per event (for example, a doorbell press).
  string event_id = 4;

  // Required. Third-party user ID.
  string agent_user_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Deprecated.
  string follow_up_token = 5 [deprecated = true];

  // Required. State of devices to update and notification metadata for devices.
  StateAndNotificationPayload payload = 3
      [(google.api.field_behavior) = REQUIRED];
}

// Response type for the
// [`ReportStateAndNotification`](#google.home.graph.v1.HomeGraphApiService.ReportStateAndNotification)
// call.
message ReportStateAndNotificationResponse {
  // Request ID copied from
  // [ReportStateAndNotificationRequest][google.home.graph.v1.ReportStateAndNotificationRequest].
  string request_id = 1;
}

// Payload containing the state and notification information for devices.
message StateAndNotificationPayload {
  // The devices for updating state and sending notifications.
  ReportStateAndNotificationDevice devices = 1;
}

// The states and notifications specific to a device.
message ReportStateAndNotificationDevice {
  // States of devices to update. See the **Device STATES** section
  // of the individual trait [reference
  // guides](https://developers.home.google.com/cloud-to-cloud/traits).
  google.protobuf.Struct states = 1;

  // Notifications metadata for devices. See the **Device NOTIFICATIONS**
  // section of the individual trait [reference
  // guides](https://developers.home.google.com/cloud-to-cloud/traits).
  google.protobuf.Struct notifications = 2;
}

// Request type for the
// [`DeleteAgentUser`](#google.home.graph.v1.HomeGraphApiService.DeleteAgentUser)
// call.
message DeleteAgentUserRequest {
  // Request ID used for debugging.
  string request_id = 1;

  // Required. Third-party user ID.
  string agent_user_id = 2 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "homegraph.googleapis.com/AgentUserPath"
    }
  ];
}

// Request type for the
// [`Query`](#google.home.graph.v1.HomeGraphApiService.Query) call.
message QueryRequest {
  // Request ID used for debugging.
  string request_id = 1;

  // Required. Third-party user ID.
  string agent_user_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Inputs containing third-party device IDs for which to
  // get the device states.
  repeated QueryRequestInput inputs = 3
      [(google.api.field_behavior) = REQUIRED];
}

// Device ID inputs to [QueryRequest][google.home.graph.v1.QueryRequest].
message QueryRequestInput {
  // Payload containing third-party device IDs.
  QueryRequestPayload payload = 1;
}

// Payload containing device IDs.
message QueryRequestPayload {
  // Third-party device IDs for which to get the device states.
  repeated AgentDeviceId devices = 1;
}

// Third-party device ID for one device.
message AgentDeviceId {
  // Third-party device ID.
  string id = 1;
}

// Response type for the
// [`Query`](#google.home.graph.v1.HomeGraphApiService.Query) call.
// This should follow the same format as the Google smart home
// `action.devices.QUERY`
// [response](https://developers.home.google.com/cloud-to-cloud/intents/query).
//
// Example:
//
// ```json
// {
//   "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
//   "payload": {
//     "devices": {
//       "123": {
//         "on": true,
//         "online": true
//       },
//       "456": {
//         "on": true,
//         "online": true,
//         "brightness": 80,
//         "color": {
//           "name": "cerulean",
//           "spectrumRGB": 31655
//         }
//       }
//     }
//   }
// }
// ```
message QueryResponse {
  // Request ID used for debugging. Copied from the request.
  string request_id = 1;

  // Device states for the devices given in the request.
  QueryResponsePayload payload = 2;
}

// Payload containing device states information.
message QueryResponsePayload {
  // States of the devices. Map of third-party device ID to struct of device
  // states.
  map<string, google.protobuf.Struct> devices = 1;
}

// Request type for the [`Sync`](#google.home.graph.v1.HomeGraphApiService.Sync)
// call.
message SyncRequest {
  // Request ID used for debugging.
  string request_id = 1;

  // Required. Third-party user ID.
  string agent_user_id = 2 [(google.api.field_behavior) = REQUIRED];
}

// Response type for the
// [`Sync`](#google.home.graph.v1.HomeGraphApiService.Sync) call.
// This should follow the same format as the Google smart home
// `action.devices.SYNC`
// [response](https://developers.home.google.com/cloud-to-cloud/intents/sync).
//
// Example:
//
// ```json
// {
//   "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
//   "payload": {
//     "agentUserId": "1836.15267389",
//     "devices": [{
//       "id": "123",
//       "type": "action.devices.types.OUTLET",
//       "traits": [
//         "action.devices.traits.OnOff"
//       ],
//       "name": {
//         "defaultNames": ["My Outlet 1234"],
//         "name": "Night light",
//         "nicknames": ["wall plug"]
//       },
//       "willReportState": false,
//       "deviceInfo": {
//         "manufacturer": "lights-out-inc",
//         "model": "hs1234",
//         "hwVersion": "3.2",
//         "swVersion": "11.4"
//       },
//       "customData": {
//         "fooValue": 74,
//         "barValue": true,
//         "bazValue": "foo"
//       }
//     }]
//   }
// }
// ```
message SyncResponse {
  // Request ID used for debugging. Copied from the request.
  string request_id = 1;

  // Devices associated with the third-party user.
  SyncResponsePayload payload = 2;
}

// Payload containing device information.
message SyncResponsePayload {
  // Third-party user ID
  string agent_user_id = 1;

  // Devices associated with the third-party user.
  repeated Device devices = 2;
}
