// Copyright 2019 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: 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/20191202")
	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/20191202")
	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/20191202")
	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/20191202")
	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/20191202")
	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"
	//   }
	// }

}
