// 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"
	internaloption "google.golang.org/api/option/internaloption"
	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
var _ = internaloption.WithDefaultEndpoint

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) {
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	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/"+gensupport.GoVersion()+" gdcl/20200316")
	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/"+gensupport.GoVersion()+" gdcl/20200316")
	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/"+gensupport.GoVersion()+" gdcl/20200316")
	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/"+gensupport.GoVersion()+" gdcl/20200316")
	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/"+gensupport.GoVersion()+" gdcl/20200316")
	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"
	//   }
	// }

}
