// Copyright 2020 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package homegraph provides access to the HomeGraph API.
//
// For product documentation, see: https://developers.google.com/actions/smarthome/create-app#request-sync
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/homegraph/v1"
//   ...
//   ctx := context.Background()
//   homegraphService, err := homegraph.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   homegraphService, err := homegraph.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
//
//   config := &oauth2.Config{...}
//   // ...
//   token, err := config.Exchange(ctx, ...)
//   homegraphService, err := homegraph.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package homegraph // import "google.golang.org/api/homegraph/v1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	htransport "google.golang.org/api/transport/http"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled

const apiId = "homegraph:v1"
const apiName = "homegraph"
const apiVersion = "v1"
const basePath = "https://homegraph.googleapis.com/"

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.AgentUsers = NewAgentUsersService(s)
	s.Devices = NewDevicesService(s)
	return s, nil
}

type Service struct {
	client    *http.Client
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	AgentUsers *AgentUsersService

	Devices *DevicesService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewAgentUsersService(s *Service) *AgentUsersService {
	rs := &AgentUsersService{s: s}
	return rs
}

type AgentUsersService struct {
	s *Service
}

func NewDevicesService(s *Service) *DevicesService {
	rs := &DevicesService{s: s}
	return rs
}

type DevicesService struct {
	s *Service
}

// AgentDeviceId: Third-party partner's device ID for one device.
type AgentDeviceId struct {
	// Id: Third-party partner's device ID.
	Id string `json:"id,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AgentDeviceId) MarshalJSON() ([]byte, error) {
	type NoMethod AgentDeviceId
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AgentOtherDeviceId: Identifies a device in the third party or first
// party system.
type AgentOtherDeviceId struct {
	// AgentId: The agent's ID. Generally it is the agent's AoG project id.
	AgentId string `json:"agentId,omitempty"`

	// DeviceId: Device ID defined by the agent. The device_id must be
	// unique.
	DeviceId string `json:"deviceId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AgentId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AgentId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AgentOtherDeviceId) MarshalJSON() ([]byte, error) {
	type NoMethod AgentOtherDeviceId
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Device: Third-party partner's device definition.
type Device struct {
	// Attributes: Attributes for the traits supported by the device.
	Attributes googleapi.RawMessage `json:"attributes,omitempty"`

	// CustomData: Custom JSON data provided by the manufacturer and
	// attached to QUERY and
	// EXECUTE requests in AoG.
	CustomData googleapi.RawMessage `json:"customData,omitempty"`

	// DeviceInfo: Device manufacturer, model, hardware version, and
	// software version.
	DeviceInfo *DeviceInfo `json:"deviceInfo,omitempty"`

	// Id: Third-party partner's device ID.
	Id string `json:"id,omitempty"`

	// Name: Name of the device given by the third party. This includes
	// names given to
	// the device via third party device manufacturer's app, model names for
	// the
	// device, etc.
	Name *DeviceNames `json:"name,omitempty"`

	// NotificationSupportedByAgent: Indicates whether the device is capable
	// of sending notifications. This
	// field will be set by the agent (partner) on an incoming SYNC. If a
	// device
	// is not capable of generating notifications, the partner should set
	// this
	// flag to false. If a partner is not capable of
	// calling
	// ReportStateAndNotification to send notifications to Google, the
	// partner
	// should set this flag to false. If there is a user setting in the
	// partner
	// app to enable notifications and it is turned off, the partner should
	// set
	// this flag to false.
	NotificationSupportedByAgent bool `json:"notificationSupportedByAgent,omitempty"`

	// OtherDeviceIds: IDs of other devices associated with this device.
	// This is used to
	// represent a device group (e.g. bonded zone) or "facets"
	// synced
	// through different flows (e.g. Google Nest Hub Max with a Nest
	// Camera).
	//
	// This may also be used to pass in alternate IDs used to identify a
	// cloud
	// synced device for local execution (i.e. local verification). If used
	// for
	// local verification, this field is synced from the cloud.
	OtherDeviceIds []*AgentOtherDeviceId `json:"otherDeviceIds,omitempty"`

	// RoomHint: If the third-party partner's cloud configuration includes
	// placing devices
	// in rooms, the name of the room can be provided here.
	RoomHint string `json:"roomHint,omitempty"`

	// StructureHint: As in roomHint, for structures that users set up in
	// the partner's system.
	StructureHint string `json:"structureHint,omitempty"`

	// Traits: Traits supported by the device.
	Traits []string `json:"traits,omitempty"`

	// Type: Hardware type of the device (e.g. light, outlet, etc).
	Type string `json:"type,omitempty"`

	// WillReportState: Indicates whether the state of this device is being
	// reported to Google
	// through ReportStateAndNotification call.
	WillReportState bool `json:"willReportState,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Attributes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Attributes") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Device) MarshalJSON() ([]byte, error) {
	type NoMethod Device
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeviceInfo: Device information.
type DeviceInfo struct {
	// HwVersion: Device hardware version.
	HwVersion string `json:"hwVersion,omitempty"`

	// Manufacturer: Device manufacturer.
	Manufacturer string `json:"manufacturer,omitempty"`

	// Model: Device model.
	Model string `json:"model,omitempty"`

	// SwVersion: Device software version.
	SwVersion string `json:"swVersion,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HwVersion") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HwVersion") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DeviceInfo) MarshalJSON() ([]byte, error) {
	type NoMethod DeviceInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeviceNames: Different names for the device.
type DeviceNames struct {
	// DefaultNames: List of names provided by the partner rather than the
	// user, often
	// manufacturer names, SKUs, etc.
	DefaultNames []string `json:"defaultNames,omitempty"`

	// Name: Primary name of the device, generally provided by the user.
	Name string `json:"name,omitempty"`

	// Nicknames: Additional names provided by the user for the device.
	Nicknames []string `json:"nicknames,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DefaultNames") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DefaultNames") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DeviceNames) MarshalJSON() ([]byte, error) {
	type NoMethod DeviceNames
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Empty: A generic empty message that you can re-use to avoid defining
// duplicated
// empty messages in your APIs. A typical example is to use it as the
// request
// or the response type of an API method. For instance:
//
//     service Foo {
//       rpc Bar(google.protobuf.Empty) returns
// (google.protobuf.Empty);
//     }
//
// The JSON representation for `Empty` is empty JSON object `{}`.
type Empty struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// QueryRequest: Request type for
// the
// [`Query`](#google.home.graph.v1.HomeGraphApiService.Query) call. This
// should
// be the same format as the Actions on Google
// `action.devices.QUERY`
// [request](/actions/smarthome/create-app#actiond
// evicesquery) with the
// exception of the extra `agent_user_id` and no `intent` and
// `customData`
// fields.
type QueryRequest struct {
	// AgentUserId: Required. Third-party user ID.
	AgentUserId string `json:"agentUserId,omitempty"`

	// Inputs: Required. Inputs containing third-party partner's device IDs
	// for which to
	// get the device states.
	Inputs []*QueryRequestInput `json:"inputs,omitempty"`

	// RequestId: Request ID used for debugging.
	RequestId string `json:"requestId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AgentUserId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AgentUserId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *QueryRequest) MarshalJSON() ([]byte, error) {
	type NoMethod QueryRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// QueryRequestInput: Device ID inputs to QueryRequest.
type QueryRequestInput struct {
	// Payload: Payload containing third-party partner's device IDs.
	Payload *QueryRequestPayload `json:"payload,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Payload") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Payload") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *QueryRequestInput) MarshalJSON() ([]byte, error) {
	type NoMethod QueryRequestInput
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// QueryRequestPayload: Payload containing device IDs.
type QueryRequestPayload struct {
	// Devices: Third-party partner's device IDs for which to get the device
	// states.
	Devices []*AgentDeviceId `json:"devices,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Devices") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Devices") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *QueryRequestPayload) MarshalJSON() ([]byte, error) {
	type NoMethod QueryRequestPayload
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// QueryResponse: Response type for
// the
// [`Query`](#google.home.graph.v1.HomeGraphApiService.Query) call. This
// should
// follow the same format as the Actions on Google
// `action.devices.QUERY`
// [response](/actions/smarthome/create-app#action
// devicesquery).
// # 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
//         }
//       }
//     }
//   }
// }
// ```
type QueryResponse struct {
	// Payload: Device states for the devices given in the request.
	Payload *QueryResponsePayload `json:"payload,omitempty"`

	// RequestId: Request ID used for debugging. Copied from the request.
	RequestId string `json:"requestId,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Payload") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Payload") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *QueryResponse) MarshalJSON() ([]byte, error) {
	type NoMethod QueryResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// QueryResponsePayload: Payload containing device states information.
type QueryResponsePayload struct {
	// Devices: States of the devices. Map of third-party device ID to
	// struct of device
	// states.
	Devices map[string]googleapi.RawMessage `json:"devices,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Devices") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Devices") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *QueryResponsePayload) MarshalJSON() ([]byte, error) {
	type NoMethod QueryResponsePayload
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReportStateAndNotificationDevice: The states and notifications
// specific to a device.
type ReportStateAndNotificationDevice struct {
	// Notifications: Notifications metadata for devices.
	Notifications googleapi.RawMessage `json:"notifications,omitempty"`

	// States: States of devices to update.
	States googleapi.RawMessage `json:"states,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Notifications") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Notifications") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReportStateAndNotificationDevice) MarshalJSON() ([]byte, error) {
	type NoMethod ReportStateAndNotificationDevice
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReportStateAndNotificationRequest: Request type for
// the
// [`ReportStateAndNotification`](#google.home.graph.v1.HomeGraphApiS
// ervice.ReportStateAndNotification)
// call. It may include States, Notifications, or both. This request
// uses
// globally unique flattened state names instead of namespaces based on
// traits
// to align with the existing QUERY and EXECUTE APIs implemented by 90+
// Smart
// Home partners. 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
//         }
//       },
//     }
//   }
// }
// ```
type ReportStateAndNotificationRequest struct {
	// AgentUserId: Required. Third-party user ID.
	AgentUserId string `json:"agentUserId,omitempty"`

	// EventId: Unique identifier per event (for example, a doorbell press).
	EventId string `json:"eventId,omitempty"`

	// FollowUpToken: Token to maintain state in the follow up notification
	// response.
	FollowUpToken string `json:"followUpToken,omitempty"`

	// Payload: Required. State of devices to update and notification
	// metadata for devices. For
	// example, if a user turns a light on manually, a state update should
	// be
	// sent so that the information is always the current status of the
	// device.
	// Notifications are independent from the state and its piece of the
	// payload
	// should contain everything necessary to notify the user. Although it
	// may be
	// related to a state change, it does not need to be. For example, if
	// a
	// device can turn on/off and change temperature, the states reported
	// would
	// include both "on" and "70 degrees" but the 3p may choose not to send
	// any
	// notification for that, or to only say that the "the room is heating
	// up",
	// keeping state and notification independent.
	Payload *StateAndNotificationPayload `json:"payload,omitempty"`

	// RequestId: Request ID used for debugging.
	RequestId string `json:"requestId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AgentUserId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AgentUserId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReportStateAndNotificationRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ReportStateAndNotificationRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReportStateAndNotificationResponse: Response type for
// the
// [`ReportStateAndNotification`](#google.home.graph.v1.HomeGraphApiS
// ervice.ReportStateAndNotification)
// call.
type ReportStateAndNotificationResponse struct {
	// RequestId: Request ID copied from ReportStateAndNotificationRequest.
	RequestId string `json:"requestId,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "RequestId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RequestId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReportStateAndNotificationResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ReportStateAndNotificationResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RequestSyncDevicesRequest: Request type for
// the
// [`RequestSyncDevices`](#google.home.graph.v1.HomeGraphApiService.R
// equestSyncDevices)
// call.
type RequestSyncDevicesRequest struct {
	// AgentUserId: Required. Third-party user ID issued by agent's
	// third-party identity
	// provider.
	AgentUserId string `json:"agentUserId,omitempty"`

	// Async: Optional. If set, the request will be added to a queue and a
	// response will
	// be returned immediately. The queue allows for de-duplication
	// of
	// simultaneous requests.
	Async bool `json:"async,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AgentUserId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AgentUserId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RequestSyncDevicesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RequestSyncDevicesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RequestSyncDevicesResponse: Response type for
// the
// [`RequestSyncDevices`](#google.home.graph.v1.HomeGraphApiService.R
// equestSyncDevices)
// call. Intentionally empty upon success. An HTTP response code is
// returned
// with more details upon failure.
type RequestSyncDevicesResponse struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// StateAndNotificationPayload: Payload containing the state and
// notification information for devices.
type StateAndNotificationPayload struct {
	// Devices: The devices for updating state and sending notifications.
	Devices *ReportStateAndNotificationDevice `json:"devices,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Devices") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Devices") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *StateAndNotificationPayload) MarshalJSON() ([]byte, error) {
	type NoMethod StateAndNotificationPayload
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SyncRequest: Request type for the
// [`Sync`](#google.home.graph.v1.HomeGraphApiService.Sync)
// call. This should follow the same format as the Actions on
// Google
// `action.devices.SYNC`
// [request](/actions/smarthome/create-app#a
// ctiondevicessync) with the exception
// of the extra `agent_user_id` and no `intent` field.
type SyncRequest struct {
	// AgentUserId: Required. Third-party user ID.
	AgentUserId string `json:"agentUserId,omitempty"`

	// RequestId: Request ID used for debugging.
	RequestId string `json:"requestId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AgentUserId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AgentUserId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SyncRequest) MarshalJSON() ([]byte, error) {
	type NoMethod SyncRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SyncResponse: Response type for
// the
// [`Sync`](#google.home.graph.v1.HomeGraphApiService.Sync) call. This
// should
// follow the same format as the Actions on Google
// `action.devices.SYNC`
// [response](/actions/smarthome/create-app#actiond
// evicessync).
// # 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"
//       }
//     }]
//   }
// }
// ```
type SyncResponse struct {
	// Payload: Devices associated with the third-party user.
	Payload *SyncResponsePayload `json:"payload,omitempty"`

	// RequestId: Request ID used for debugging. Copied from the request.
	RequestId string `json:"requestId,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Payload") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Payload") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SyncResponse) MarshalJSON() ([]byte, error) {
	type NoMethod SyncResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SyncResponsePayload: Payload containing device information.
type SyncResponsePayload struct {
	// AgentUserId: Third-party user ID
	AgentUserId string `json:"agentUserId,omitempty"`

	// Devices: Devices associated with the third-party user.
	Devices []*Device `json:"devices,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AgentUserId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AgentUserId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SyncResponsePayload) MarshalJSON() ([]byte, error) {
	type NoMethod SyncResponsePayload
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "homegraph.agentUsers.delete":

type AgentUsersDeleteCall struct {
	s           *Service
	agentUserId string
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Delete: Unlinks an agent user from Google. As a result, all data
// related to this
// user will be deleted.
//
// Here is how the agent user is created in Google:
//
// 1.  When a user opens their Google Home App, they can begin linking a
// 3p
//     partner.
// 2.  User is guided through the OAuth process.
// 3.  After entering the 3p credentials, Google gets the 3p OAuth token
// and
//     uses it to make a Sync call to the 3p partner and gets back all
// of the
//     user's data, including `agent_user_id` and devices.
// 4.  Google creates the agent user and stores a mapping from the
//     `agent_user_id` -> Google ID mapping. Google also
//     stores all of the user's devices under that Google ID.
//
// The mapping from `agent_user_id` to Google ID is many to many, since
// one
// Google user can have multiple 3p accounts, and multiple Google users
// can
// map to one `agent_user_id` (e.g., a husband and wife share one Nest
// account
// username/password).
//
// The third-party user's identity is passed in as `agent_user_id`.
// The agent is identified by the JWT signed by the partner's service
// account.
//
// Note: Special characters (except "/") in `agent_user_id` must
// be
// URL-encoded.
func (r *AgentUsersService) Delete(agentUserId string) *AgentUsersDeleteCall {
	c := &AgentUsersDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.agentUserId = agentUserId
	return c
}

// RequestId sets the optional parameter "requestId": Request ID used
// for debugging.
func (c *AgentUsersDeleteCall) RequestId(requestId string) *AgentUsersDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AgentUsersDeleteCall) Fields(s ...googleapi.Field) *AgentUsersDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AgentUsersDeleteCall) Context(ctx context.Context) *AgentUsersDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AgentUsersDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AgentUsersDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200212")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+agentUserId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"agentUserId": c.agentUserId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "homegraph.agentUsers.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AgentUsersDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Unlinks an agent user from Google. As a result, all data related to this\nuser will be deleted.\n\nHere is how the agent user is created in Google:\n\n1.  When a user opens their Google Home App, they can begin linking a 3p\n    partner.\n2.  User is guided through the OAuth process.\n3.  After entering the 3p credentials, Google gets the 3p OAuth token and\n    uses it to make a Sync call to the 3p partner and gets back all of the\n    user's data, including `agent_user_id` and devices.\n4.  Google creates the agent user and stores a mapping from the\n    `agent_user_id` -\u003e Google ID mapping. Google also\n    stores all of the user's devices under that Google ID.\n\nThe mapping from `agent_user_id` to Google ID is many to many, since one\nGoogle user can have multiple 3p accounts, and multiple Google users can\nmap to one `agent_user_id` (e.g., a husband and wife share one Nest account\nusername/password).\n\nThe third-party user's identity is passed in as `agent_user_id`.\nThe agent is identified by the JWT signed by the partner's service account.\n\nNote: Special characters (except \"/\") in `agent_user_id` must be\nURL-encoded.",
	//   "flatPath": "v1/agentUsers/{agentUsersId}",
	//   "httpMethod": "DELETE",
	//   "id": "homegraph.agentUsers.delete",
	//   "parameterOrder": [
	//     "agentUserId"
	//   ],
	//   "parameters": {
	//     "agentUserId": {
	//       "description": "Required. Third-party user ID.",
	//       "location": "path",
	//       "pattern": "^agentUsers/.+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "Request ID used for debugging.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+agentUserId}",
	//   "response": {
	//     "$ref": "Empty"
	//   }
	// }

}

// method id "homegraph.devices.query":

type DevicesQueryCall struct {
	s            *Service
	queryrequest *QueryRequest
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Query: Gets the device states for the devices in QueryRequest.
// The third-party user's identity is passed in as `agent_user_id`. The
// agent
// is identified by the JWT signed by the third-party partner's
// service
// account.
func (r *DevicesService) Query(queryrequest *QueryRequest) *DevicesQueryCall {
	c := &DevicesQueryCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.queryrequest = queryrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DevicesQueryCall) Fields(s ...googleapi.Field) *DevicesQueryCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DevicesQueryCall) Context(ctx context.Context) *DevicesQueryCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DevicesQueryCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DevicesQueryCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200212")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.queryrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/devices:query")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "homegraph.devices.query" call.
// Exactly one of *QueryResponse or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *QueryResponse.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DevicesQueryCall) Do(opts ...googleapi.CallOption) (*QueryResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &QueryResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the device states for the devices in QueryRequest.\nThe third-party user's identity is passed in as `agent_user_id`. The agent\nis identified by the JWT signed by the third-party partner's service\naccount.",
	//   "flatPath": "v1/devices:query",
	//   "httpMethod": "POST",
	//   "id": "homegraph.devices.query",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/devices:query",
	//   "request": {
	//     "$ref": "QueryRequest"
	//   },
	//   "response": {
	//     "$ref": "QueryResponse"
	//   }
	// }

}

// method id "homegraph.devices.reportStateAndNotification":

type DevicesReportStateAndNotificationCall struct {
	s                                 *Service
	reportstateandnotificationrequest *ReportStateAndNotificationRequest
	urlParams_                        gensupport.URLParams
	ctx_                              context.Context
	header_                           http.Header
}

// ReportStateAndNotification: Reports device state and optionally sends
// device notifications. Called by
// an agent when the device state of a third-party changes or the agent
// wants
// to send a notification about the device. See
// [Implement Report State](/actions/smarthome/report-state) for
// more
// information.
// This method updates a predefined set of states for a device, which
// all
// devices have according to their prescribed traits (for example, a
// light
// will have the [OnOff](/actions/smarthome/traits/onoff) trait that
// reports
// the state `on` as a boolean value).
// A new state may not be created and an INVALID_ARGUMENT code will be
// thrown
// if so. It also optionally takes in a list of Notifications that may
// be
// created, which are associated to this state change.
//
// The third-party user's identity is passed in as `agent_user_id`.
// The agent is identified by the JWT signed by the partner's service
// account.
func (r *DevicesService) ReportStateAndNotification(reportstateandnotificationrequest *ReportStateAndNotificationRequest) *DevicesReportStateAndNotificationCall {
	c := &DevicesReportStateAndNotificationCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.reportstateandnotificationrequest = reportstateandnotificationrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DevicesReportStateAndNotificationCall) Fields(s ...googleapi.Field) *DevicesReportStateAndNotificationCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DevicesReportStateAndNotificationCall) Context(ctx context.Context) *DevicesReportStateAndNotificationCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DevicesReportStateAndNotificationCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DevicesReportStateAndNotificationCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200212")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.reportstateandnotificationrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/devices:reportStateAndNotification")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "homegraph.devices.reportStateAndNotification" call.
// Exactly one of *ReportStateAndNotificationResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ReportStateAndNotificationResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *DevicesReportStateAndNotificationCall) Do(opts ...googleapi.CallOption) (*ReportStateAndNotificationResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ReportStateAndNotificationResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Reports device state and optionally sends device notifications. Called by\nan agent when the device state of a third-party changes or the agent wants\nto send a notification about the device. See\n[Implement Report State](/actions/smarthome/report-state) for more\ninformation.\nThis method updates a predefined set of states for a device, which all\ndevices have according to their prescribed traits (for example, a light\nwill have the [OnOff](/actions/smarthome/traits/onoff) trait that reports\nthe state `on` as a boolean value).\nA new state may not be created and an INVALID_ARGUMENT code will be thrown\nif so. It also optionally takes in a list of Notifications that may be\ncreated, which are associated to this state change.\n\nThe third-party user's identity is passed in as `agent_user_id`.\nThe agent is identified by the JWT signed by the partner's service account.",
	//   "flatPath": "v1/devices:reportStateAndNotification",
	//   "httpMethod": "POST",
	//   "id": "homegraph.devices.reportStateAndNotification",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/devices:reportStateAndNotification",
	//   "request": {
	//     "$ref": "ReportStateAndNotificationRequest"
	//   },
	//   "response": {
	//     "$ref": "ReportStateAndNotificationResponse"
	//   }
	// }

}

// method id "homegraph.devices.requestSync":

type DevicesRequestSyncCall struct {
	s                         *Service
	requestsyncdevicesrequest *RequestSyncDevicesRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// RequestSync: Requests a `SYNC` call from Google to a 3p partner's
// home control agent for
// a user.
//
//
// The third-party user's identity is passed in as `agent_user_id`
// (see RequestSyncDevicesRequest) and forwarded back to the agent.
// The agent is identified by the API key or JWT signed by the
// partner's
// service account.
func (r *DevicesService) RequestSync(requestsyncdevicesrequest *RequestSyncDevicesRequest) *DevicesRequestSyncCall {
	c := &DevicesRequestSyncCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.requestsyncdevicesrequest = requestsyncdevicesrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DevicesRequestSyncCall) Fields(s ...googleapi.Field) *DevicesRequestSyncCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DevicesRequestSyncCall) Context(ctx context.Context) *DevicesRequestSyncCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DevicesRequestSyncCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DevicesRequestSyncCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200212")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.requestsyncdevicesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/devices:requestSync")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "homegraph.devices.requestSync" call.
// Exactly one of *RequestSyncDevicesResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *RequestSyncDevicesResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DevicesRequestSyncCall) Do(opts ...googleapi.CallOption) (*RequestSyncDevicesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RequestSyncDevicesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Requests a `SYNC` call from Google to a 3p partner's home control agent for\na user.\n\n\nThe third-party user's identity is passed in as `agent_user_id`\n(see RequestSyncDevicesRequest) and forwarded back to the agent.\nThe agent is identified by the API key or JWT signed by the partner's\nservice account.",
	//   "flatPath": "v1/devices:requestSync",
	//   "httpMethod": "POST",
	//   "id": "homegraph.devices.requestSync",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/devices:requestSync",
	//   "request": {
	//     "$ref": "RequestSyncDevicesRequest"
	//   },
	//   "response": {
	//     "$ref": "RequestSyncDevicesResponse"
	//   }
	// }

}

// method id "homegraph.devices.sync":

type DevicesSyncCall struct {
	s           *Service
	syncrequest *SyncRequest
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Sync: Gets all the devices associated with the given third-party
// user.
// The third-party user's identity is passed in as `agent_user_id`. The
// agent
// is identified by the JWT signed by the third-party partner's
// service
// account.
func (r *DevicesService) Sync(syncrequest *SyncRequest) *DevicesSyncCall {
	c := &DevicesSyncCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.syncrequest = syncrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DevicesSyncCall) Fields(s ...googleapi.Field) *DevicesSyncCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DevicesSyncCall) Context(ctx context.Context) *DevicesSyncCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DevicesSyncCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DevicesSyncCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200212")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.syncrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/devices:sync")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "homegraph.devices.sync" call.
// Exactly one of *SyncResponse or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *SyncResponse.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *DevicesSyncCall) Do(opts ...googleapi.CallOption) (*SyncResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SyncResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets all the devices associated with the given third-party user.\nThe third-party user's identity is passed in as `agent_user_id`. The agent\nis identified by the JWT signed by the third-party partner's service\naccount.",
	//   "flatPath": "v1/devices:sync",
	//   "httpMethod": "POST",
	//   "id": "homegraph.devices.sync",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/devices:sync",
	//   "request": {
	//     "$ref": "SyncRequest"
	//   },
	//   "response": {
	//     "$ref": "SyncResponse"
	//   }
	// }

}
