// 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 fcm provides access to the Firebase Cloud Messaging API.
//
// For product documentation, see: https://firebase.google.com/docs/cloud-messaging
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/fcm/v1"
//   ...
//   ctx := context.Background()
//   fcmService, err := fcm.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:
//
//   fcmService, err := fcm.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, ...)
//   fcmService, err := fcm.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package fcm // import "google.golang.org/api/fcm/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 = "fcm:v1"
const apiName = "fcm"
const apiVersion = "v1"
const basePath = "https://fcm.googleapis.com/"
const mtlsBasePath = "https://fcm.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// View and manage your data across Google Cloud Platform services
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/cloud-platform",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	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.Projects = NewProjectsService(s)
	return s, nil
}

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

	Projects *ProjectsService
}

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

func NewProjectsService(s *Service) *ProjectsService {
	rs := &ProjectsService{s: s}
	rs.Messages = NewProjectsMessagesService(s)
	return rs
}

type ProjectsService struct {
	s *Service

	Messages *ProjectsMessagesService
}

func NewProjectsMessagesService(s *Service) *ProjectsMessagesService {
	rs := &ProjectsMessagesService{s: s}
	return rs
}

type ProjectsMessagesService struct {
	s *Service
}

// AndroidConfig: Android specific options for messages sent through
// [FCM connection server](https://goo.gl/4GLdUl).
type AndroidConfig struct {
	// CollapseKey: An identifier of a group of messages that can be
	// collapsed, so that only the last message gets sent when delivery can
	// be resumed. A maximum of 4 different collapse keys is allowed at any
	// given time.
	CollapseKey string `json:"collapseKey,omitempty"`

	// Data: Arbitrary key/value payload. If present, it will override
	// google.firebase.fcm.v1.Message.data.
	Data map[string]string `json:"data,omitempty"`

	// DirectBootOk: If set to true, messages will be allowed to be
	// delivered to the app while the device is in direct boot mode. See
	// [Support Direct Boot
	// mode](https://developer.android.com/training/articles/direct-boot).
	DirectBootOk bool `json:"directBootOk,omitempty"`

	// FcmOptions: Options for features provided by the FCM SDK for Android.
	FcmOptions *AndroidFcmOptions `json:"fcmOptions,omitempty"`

	// Notification: Notification to send to android devices.
	Notification *AndroidNotification `json:"notification,omitempty"`

	// Priority: Message priority. Can take "normal" and "high" values. For
	// more information, see [Setting the priority of a
	// message](https://goo.gl/GjONJv).
	//
	// Possible values:
	//   "NORMAL" - Default priority for data messages. Normal priority
	// messages won't open network connections on a sleeping device, and
	// their delivery may be delayed to conserve the battery. For less
	// time-sensitive messages, such as notifications of new email or other
	// data to sync, choose normal delivery priority.
	//   "HIGH" - Default priority for notification messages. FCM attempts
	// to deliver high priority messages immediately, allowing the FCM
	// service to wake a sleeping device when possible and open a network
	// connection to your app server. Apps with instant messaging, chat, or
	// voice call alerts, for example, generally need to open a network
	// connection and make sure FCM delivers the message to the device
	// without delay. Set high priority if the message is time-critical and
	// requires the user's immediate interaction, but beware that setting
	// your messages to high priority contributes more to battery drain
	// compared with normal priority messages.
	Priority string `json:"priority,omitempty"`

	// RestrictedPackageName: Package name of the application where the
	// registration token must match in order to receive the message.
	RestrictedPackageName string `json:"restrictedPackageName,omitempty"`

	// Ttl: How long (in seconds) the message should be kept in FCM storage
	// if the device is offline. The maximum time to live supported is 4
	// weeks, and the default value is 4 weeks if not set. Set it to 0 if
	// want to send the message immediately. In JSON format, the Duration
	// type is encoded as a string rather than an object, where the string
	// ends in the suffix "s" (indicating seconds) and is preceded by the
	// number of seconds, with nanoseconds expressed as fractional seconds.
	// For example, 3 seconds with 0 nanoseconds should be encoded in JSON
	// format as "3s", while 3 seconds and 1 nanosecond should be expressed
	// in JSON format as "3.000000001s". The ttl will be rounded down to the
	// nearest second.
	Ttl string `json:"ttl,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CollapseKey") 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. "CollapseKey") 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 *AndroidConfig) MarshalJSON() ([]byte, error) {
	type NoMethod AndroidConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AndroidFcmOptions: Options for features provided by the FCM SDK for
// Android.
type AndroidFcmOptions struct {
	// AnalyticsLabel: Label associated with the message's analytics data.
	AnalyticsLabel string `json:"analyticsLabel,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnalyticsLabel") 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. "AnalyticsLabel") 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 *AndroidFcmOptions) MarshalJSON() ([]byte, error) {
	type NoMethod AndroidFcmOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AndroidNotification: Notification to send to android devices.
type AndroidNotification struct {
	// Body: The notification's body text. If present, it will override
	// google.firebase.fcm.v1.Notification.body.
	Body string `json:"body,omitempty"`

	// BodyLocArgs: Variable string values to be used in place of the format
	// specifiers in body_loc_key to use to localize the body text to the
	// user's current localization. See [Formatting and
	// Styling](https://goo.gl/MalYE3) for more information.
	BodyLocArgs []string `json:"bodyLocArgs,omitempty"`

	// BodyLocKey: The key to the body string in the app's string resources
	// to use to localize the body text to the user's current localization.
	// See [String Resources](https://goo.gl/NdFZGI) for more information.
	BodyLocKey string `json:"bodyLocKey,omitempty"`

	// ChannelId: The [notification's channel
	// id](https://developer.android.com/guide/topics/ui/notifiers/notificati
	// ons#ManageChannels) (new in Android O). The app must create a channel
	// with this channel ID before any notification with this channel ID is
	// received. If you don't send this channel ID in the request, or if the
	// channel ID provided has not yet been created by the app, FCM uses the
	// channel ID specified in the app manifest.
	ChannelId string `json:"channelId,omitempty"`

	// ClickAction: The action associated with a user click on the
	// notification. If specified, an activity with a matching intent filter
	// is launched when a user clicks on the notification.
	ClickAction string `json:"clickAction,omitempty"`

	// Color: The notification's icon color, expressed in #rrggbb format.
	Color string `json:"color,omitempty"`

	// DefaultLightSettings: If set to true, use the Android framework's
	// default LED light settings for the notification. Default values are
	// specified in
	// [config.xml](https://android.googlesource.com/platform/frameworks/base
	// /+/master/core/res/res/values/config.xml). If
	// `default_light_settings` is set to true and `light_settings` is also
	// set, the user-specified `light_settings` is used instead of the
	// default value.
	DefaultLightSettings bool `json:"defaultLightSettings,omitempty"`

	// DefaultSound: If set to true, use the Android framework's default
	// sound for the notification. Default values are specified in
	// [config.xml](https://android.googlesource.com/platform/frameworks/base
	// /+/master/core/res/res/values/config.xml).
	DefaultSound bool `json:"defaultSound,omitempty"`

	// DefaultVibrateTimings: If set to true, use the Android framework's
	// default vibrate pattern for the notification. Default values are
	// specified in
	// [config.xml](https://android.googlesource.com/platform/frameworks/base
	// /+/master/core/res/res/values/config.xml). If
	// `default_vibrate_timings` is set to true and `vibrate_timings` is
	// also set, the default value is used instead of the user-specified
	// `vibrate_timings`.
	DefaultVibrateTimings bool `json:"defaultVibrateTimings,omitempty"`

	// EventTime: Set the time that the event in the notification occurred.
	// Notifications in the panel are sorted by this time. A point in time
	// is represented using
	// [protobuf.Timestamp](https://developers.google.com/protocol-buffers/do
	// cs/reference/java/com/google/protobuf/Timestamp).
	EventTime string `json:"eventTime,omitempty"`

	// Icon: The notification's icon. Sets the notification icon to myicon
	// for drawable resource myicon. If you don't send this key in the
	// request, FCM displays the launcher icon specified in your app
	// manifest.
	Icon string `json:"icon,omitempty"`

	// Image: Contains the URL of an image that is going to be displayed in
	// a notification. If present, it will override
	// google.firebase.fcm.v1.Notification.image.
	Image string `json:"image,omitempty"`

	// LightSettings: Settings to control the notification's LED blinking
	// rate and color if LED is available on the device. The total blinking
	// time is controlled by the OS.
	LightSettings *LightSettings `json:"lightSettings,omitempty"`

	// LocalOnly: Set whether or not this notification is relevant only to
	// the current device. Some notifications can be bridged to other
	// devices for remote display, such as a Wear OS watch. This hint can be
	// set to recommend this notification not be bridged. See [Wear OS
	// guides](https://developer.android.com/training/wearables/notifications
	// /bridger#existing-method-of-preventing-bridging)
	LocalOnly bool `json:"localOnly,omitempty"`

	// NotificationCount: Sets the number of items this notification
	// represents. May be displayed as a badge count for launchers that
	// support badging.See [Notification
	// Badge](https://developer.android.com/training/notify-user/badges).
	// For example, this might be useful if you're using just one
	// notification to represent multiple new messages but you want the
	// count here to represent the number of total new messages. If zero or
	// unspecified, systems that support badging use the default, which is
	// to increment a number displayed on the long-press menu each time a
	// new notification arrives.
	NotificationCount int64 `json:"notificationCount,omitempty"`

	// NotificationPriority: Set the relative priority for this
	// notification. Priority is an indication of how much of the user's
	// attention should be consumed by this notification. Low-priority
	// notifications may be hidden from the user in certain situations,
	// while the user might be interrupted for a higher-priority
	// notification. The effect of setting the same priorities may differ
	// slightly on different platforms. Note this priority differs from
	// `AndroidMessagePriority`. This priority is processed by the client
	// after the message has been delivered, whereas
	// [AndroidMessagePriority](https://firebase.google.com/docs/reference/fc
	// m/rest/v1/projects.messages#androidmessagepriority) is an FCM concept
	// that controls when the message is delivered.
	//
	// Possible values:
	//   "PRIORITY_UNSPECIFIED" - If priority is unspecified, notification
	// priority is set to `PRIORITY_DEFAULT`.
	//   "PRIORITY_MIN" - Lowest notification priority. Notifications with
	// this `PRIORITY_MIN` might not be shown to the user except under
	// special circumstances, such as detailed notification logs.
	//   "PRIORITY_LOW" - Lower notification priority. The UI may choose to
	// show the notifications smaller, or at a different position in the
	// list, compared with notifications with `PRIORITY_DEFAULT`.
	//   "PRIORITY_DEFAULT" - Default notification priority. If the
	// application does not prioritize its own notifications, use this value
	// for all notifications.
	//   "PRIORITY_HIGH" - Higher notification priority. Use this for more
	// important notifications or alerts. The UI may choose to show these
	// notifications larger, or at a different position in the notification
	// lists, compared with notifications with `PRIORITY_DEFAULT`.
	//   "PRIORITY_MAX" - Highest notification priority. Use this for the
	// application's most important items that require the user's prompt
	// attention or input.
	NotificationPriority string `json:"notificationPriority,omitempty"`

	// Sound: The sound to play when the device receives the notification.
	// Supports "default" or the filename of a sound resource bundled in the
	// app. Sound files must reside in /res/raw/.
	Sound string `json:"sound,omitempty"`

	// Sticky: When set to false or unset, the notification is automatically
	// dismissed when the user clicks it in the panel. When set to true, the
	// notification persists even when the user clicks it.
	Sticky bool `json:"sticky,omitempty"`

	// Tag: Identifier used to replace existing notifications in the
	// notification drawer. If not specified, each request creates a new
	// notification. If specified and a notification with the same tag is
	// already being shown, the new notification replaces the existing one
	// in the notification drawer.
	Tag string `json:"tag,omitempty"`

	// Ticker: Sets the "ticker" text, which is sent to accessibility
	// services. Prior to API level 21 (`Lollipop`), sets the text that is
	// displayed in the status bar when the notification first arrives.
	Ticker string `json:"ticker,omitempty"`

	// Title: The notification's title. If present, it will override
	// google.firebase.fcm.v1.Notification.title.
	Title string `json:"title,omitempty"`

	// TitleLocArgs: Variable string values to be used in place of the
	// format specifiers in title_loc_key to use to localize the title text
	// to the user's current localization. See [Formatting and
	// Styling](https://goo.gl/MalYE3) for more information.
	TitleLocArgs []string `json:"titleLocArgs,omitempty"`

	// TitleLocKey: The key to the title string in the app's string
	// resources to use to localize the title text to the user's current
	// localization. See [String Resources](https://goo.gl/NdFZGI) for more
	// information.
	TitleLocKey string `json:"titleLocKey,omitempty"`

	// VibrateTimings: Set the vibration pattern to use. Pass in an array of
	// [protobuf.Duration](https://developers.google.com/protocol-buffers/doc
	// s/reference/google.protobuf#google.protobuf.Duration) to turn on or
	// off the vibrator. The first value indicates the `Duration` to wait
	// before turning the vibrator on. The next value indicates the
	// `Duration` to keep the vibrator on. Subsequent values alternate
	// between `Duration` to turn the vibrator off and to turn the vibrator
	// on. If `vibrate_timings` is set and `default_vibrate_timings` is set
	// to `true`, the default value is used instead of the user-specified
	// `vibrate_timings`.
	VibrateTimings []string `json:"vibrateTimings,omitempty"`

	// Visibility: Set the
	// [Notification.visibility](https://developer.android.com/reference/andr
	// oid/app/Notification.html#visibility) of the notification.
	//
	// Possible values:
	//   "VISIBILITY_UNSPECIFIED" - If unspecified, default to
	// `Visibility.PRIVATE`.
	//   "PRIVATE" - Show this notification on all lockscreens, but conceal
	// sensitive or private information on secure lockscreens.
	//   "PUBLIC" - Show this notification in its entirety on all
	// lockscreens.
	//   "SECRET" - Do not reveal any part of this notification on a secure
	// lockscreen.
	Visibility string `json:"visibility,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Body") 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. "Body") 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 *AndroidNotification) MarshalJSON() ([]byte, error) {
	type NoMethod AndroidNotification
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ApnsConfig: [Apple Push Notification Service](https://goo.gl/MXRTPa)
// specific options.
type ApnsConfig struct {
	// FcmOptions: Options for features provided by the FCM SDK for iOS.
	FcmOptions *ApnsFcmOptions `json:"fcmOptions,omitempty"`

	// Headers: HTTP request headers defined in Apple Push Notification
	// Service. Refer to [APNs request
	// headers](https://developer.apple.com/documentation/usernotifications/s
	// etting_up_a_remote_notification_server/sending_notification_requests_t
	// o_apns) for supported headers, e.g. "apns-priority": "10".
	Headers map[string]string `json:"headers,omitempty"`

	// Payload: APNs payload as a JSON object, including both `aps`
	// dictionary and custom payload. See [Payload Key
	// Reference](https://developer.apple.com/documentation/usernotifications
	// /setting_up_a_remote_notification_server/generating_a_remote_notificat
	// ion). If present, it overrides
	// google.firebase.fcm.v1.Notification.title and
	// google.firebase.fcm.v1.Notification.body.
	Payload googleapi.RawMessage `json:"payload,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FcmOptions") 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. "FcmOptions") 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 *ApnsConfig) MarshalJSON() ([]byte, error) {
	type NoMethod ApnsConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ApnsFcmOptions: Options for features provided by the FCM SDK for iOS.
type ApnsFcmOptions struct {
	// AnalyticsLabel: Label associated with the message's analytics data.
	AnalyticsLabel string `json:"analyticsLabel,omitempty"`

	// Image: Contains the URL of an image that is going to be displayed in
	// a notification. If present, it will override
	// google.firebase.fcm.v1.Notification.image.
	Image string `json:"image,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnalyticsLabel") 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. "AnalyticsLabel") 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 *ApnsFcmOptions) MarshalJSON() ([]byte, error) {
	type NoMethod ApnsFcmOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Color: Represents a color in the RGBA color space. This
// representation is designed for simplicity of conversion to/from color
// representations in various languages over compactness; for example,
// the fields of this representation can be trivially provided to the
// constructor of "java.awt.Color" in Java; it can also be trivially
// provided to UIColor's "+colorWithRed:green:blue:alpha" method in iOS;
// and, with just a little work, it can be easily formatted into a CSS
// "rgba()" string in JavaScript, as well. Note: this proto does not
// carry information about the absolute color space that should be used
// to interpret the RGB value (e.g. sRGB, Adobe RGB, DCI-P3, BT.2020,
// etc.). By default, applications SHOULD assume the sRGB color space.
// Note: when color equality needs to be decided, implementations,
// unless documented otherwise, will treat two colors to be equal if all
// their red, green, blue and alpha values each differ by at most 1e-5.
// Example (Java): import com.google.type.Color; // ... public static
// java.awt.Color fromProto(Color protocolor) { float alpha =
// protocolor.hasAlpha() ? protocolor.getAlpha().getValue() : 1.0;
// return new java.awt.Color( protocolor.getRed(),
// protocolor.getGreen(), protocolor.getBlue(), alpha); } public static
// Color toProto(java.awt.Color color) { float red = (float)
// color.getRed(); float green = (float) color.getGreen(); float blue =
// (float) color.getBlue(); float denominator = 255.0; Color.Builder
// resultBuilder = Color .newBuilder() .setRed(red / denominator)
// .setGreen(green / denominator) .setBlue(blue / denominator); int
// alpha = color.getAlpha(); if (alpha != 255) { result.setAlpha(
// FloatValue .newBuilder() .setValue(((float) alpha) / denominator)
// .build()); } return resultBuilder.build(); } // ... Example (iOS /
// Obj-C): // ... static UIColor* fromProto(Color* protocolor) { float
// red = [protocolor red]; float green = [protocolor green]; float blue
// = [protocolor blue]; FloatValue* alpha_wrapper = [protocolor alpha];
// float alpha = 1.0; if (alpha_wrapper != nil) { alpha = [alpha_wrapper
// value]; } return [UIColor colorWithRed:red green:green blue:blue
// alpha:alpha]; } static Color* toProto(UIColor* color) { CGFloat red,
// green, blue, alpha; if (![color getRed:&red green:&green blue:&blue
// alpha:&alpha]) { return nil; } Color* result = [[Color alloc] init];
// [result setRed:red]; [result setGreen:green]; [result setBlue:blue];
// if (alpha <= 0.9999) { [result
// setAlpha:floatWrapperWithValue(alpha)]; } [result autorelease];
// return result; } // ... Example (JavaScript): // ... var
// protoToCssColor = function(rgb_color) { var redFrac = rgb_color.red
// || 0.0; var greenFrac = rgb_color.green || 0.0; var blueFrac =
// rgb_color.blue || 0.0; var red = Math.floor(redFrac * 255); var green
// = Math.floor(greenFrac * 255); var blue = Math.floor(blueFrac * 255);
// if (!('alpha' in rgb_color)) { return rgbToCssColor_(red, green,
// blue); } var alphaFrac = rgb_color.alpha.value || 0.0; var rgbParams
// = [red, green, blue].join(','); return ['rgba(', rgbParams, ',',
// alphaFrac, ')'].join(''); }; var rgbToCssColor_ = function(red,
// green, blue) { var rgbNumber = new Number((red << 16) | (green << 8)
// | blue); var hexString = rgbNumber.toString(16); var missingZeros = 6
// - hexString.length; var resultBuilder = ['#']; for (var i = 0; i <
// missingZeros; i++) { resultBuilder.push('0'); }
// resultBuilder.push(hexString); return resultBuilder.join(''); }; //
// ...
type Color struct {
	// Alpha: The fraction of this color that should be applied to the
	// pixel. That is, the final pixel color is defined by the equation:
	// pixel color = alpha * (this color) + (1.0 - alpha) * (background
	// color) This means that a value of 1.0 corresponds to a solid color,
	// whereas a value of 0.0 corresponds to a completely transparent color.
	// This uses a wrapper message rather than a simple float scalar so that
	// it is possible to distinguish between a default value and the value
	// being unset. If omitted, this color object is to be rendered as a
	// solid color (as if the alpha value had been explicitly given with a
	// value of 1.0).
	Alpha float64 `json:"alpha,omitempty"`

	// Blue: The amount of blue in the color as a value in the interval [0,
	// 1].
	Blue float64 `json:"blue,omitempty"`

	// Green: The amount of green in the color as a value in the interval
	// [0, 1].
	Green float64 `json:"green,omitempty"`

	// Red: The amount of red in the color as a value in the interval [0,
	// 1].
	Red float64 `json:"red,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alpha") 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. "Alpha") 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 *Color) MarshalJSON() ([]byte, error) {
	type NoMethod Color
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *Color) UnmarshalJSON(data []byte) error {
	type NoMethod Color
	var s1 struct {
		Alpha gensupport.JSONFloat64 `json:"alpha"`
		Blue  gensupport.JSONFloat64 `json:"blue"`
		Green gensupport.JSONFloat64 `json:"green"`
		Red   gensupport.JSONFloat64 `json:"red"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Alpha = float64(s1.Alpha)
	s.Blue = float64(s1.Blue)
	s.Green = float64(s1.Green)
	s.Red = float64(s1.Red)
	return nil
}

// FcmOptions: Platform independent options for features provided by the
// FCM SDKs.
type FcmOptions struct {
	// AnalyticsLabel: Label associated with the message's analytics data.
	AnalyticsLabel string `json:"analyticsLabel,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnalyticsLabel") 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. "AnalyticsLabel") 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 *FcmOptions) MarshalJSON() ([]byte, error) {
	type NoMethod FcmOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LightSettings: Settings to control notification LED.
type LightSettings struct {
	// Color: Required. Set `color` of the LED with
	// [google.type.Color](https://github.com/googleapis/googleapis/blob/mast
	// er/google/type/color.proto).
	Color *Color `json:"color,omitempty"`

	// LightOffDuration: Required. Along with `light_on_duration `, define
	// the blink rate of LED flashes. Resolution defined by
	// [proto.Duration](https://developers.google.com/protocol-buffers/docs/r
	// eference/google.protobuf#google.protobuf.Duration)
	LightOffDuration string `json:"lightOffDuration,omitempty"`

	// LightOnDuration: Required. Along with `light_off_duration`, define
	// the blink rate of LED flashes. Resolution defined by
	// [proto.Duration](https://developers.google.com/protocol-buffers/docs/r
	// eference/google.protobuf#google.protobuf.Duration)
	LightOnDuration string `json:"lightOnDuration,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Color") 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. "Color") 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 *LightSettings) MarshalJSON() ([]byte, error) {
	type NoMethod LightSettings
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Message: Message to send by Firebase Cloud Messaging Service.
type Message struct {
	// Android: Input only. Android specific options for messages sent
	// through [FCM connection server](https://goo.gl/4GLdUl).
	Android *AndroidConfig `json:"android,omitempty"`

	// Apns: Input only. [Apple Push Notification
	// Service](https://goo.gl/MXRTPa) specific options.
	Apns *ApnsConfig `json:"apns,omitempty"`

	// Condition: Condition to send a message to, e.g. "'foo' in topics &&
	// 'bar' in topics".
	Condition string `json:"condition,omitempty"`

	// Data: Input only. Arbitrary key/value payload. The key should not be
	// a reserved word ("from", "message_type", or any word starting with
	// "google" or "gcm").
	Data map[string]string `json:"data,omitempty"`

	// FcmOptions: Input only. Template for FCM SDK feature options to use
	// across all platforms.
	FcmOptions *FcmOptions `json:"fcmOptions,omitempty"`

	// Name: Output Only. The identifier of the message sent, in the format
	// of `projects/*/messages/{message_id}`.
	Name string `json:"name,omitempty"`

	// Notification: Input only. Basic notification template to use across
	// all platforms.
	Notification *Notification `json:"notification,omitempty"`

	// Token: Registration token to send a message to.
	Token string `json:"token,omitempty"`

	// Topic: Topic name to send a message to, e.g. "weather". Note:
	// "/topics/" prefix should not be provided.
	Topic string `json:"topic,omitempty"`

	// Webpush: Input only. [Webpush
	// protocol](https://tools.ietf.org/html/rfc8030) options.
	Webpush *WebpushConfig `json:"webpush,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Android") 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. "Android") 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 *Message) MarshalJSON() ([]byte, error) {
	type NoMethod Message
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Notification: Basic notification template to use across all
// platforms.
type Notification struct {
	// Body: The notification's body text.
	Body string `json:"body,omitempty"`

	// Image: Contains the URL of an image that is going to be downloaded on
	// the device and displayed in a notification. JPEG, PNG, BMP have full
	// support across platforms. Animated GIF and video only work on iOS.
	// WebP and HEIF have varying levels of support across platforms and
	// platform versions. Android has 1MB image size limit. Quota usage and
	// implications/costs for hosting image on Firebase Storage:
	// https://firebase.google.com/pricing
	Image string `json:"image,omitempty"`

	// Title: The notification's title.
	Title string `json:"title,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Body") 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. "Body") 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 *Notification) MarshalJSON() ([]byte, error) {
	type NoMethod Notification
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SendMessageRequest: Request to send a message to specified target.
type SendMessageRequest struct {
	// Message: Required. Message to send.
	Message *Message `json:"message,omitempty"`

	// ValidateOnly: Flag for testing the request without actually
	// delivering the message.
	ValidateOnly bool `json:"validateOnly,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Message") 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. "Message") 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 *SendMessageRequest) MarshalJSON() ([]byte, error) {
	type NoMethod SendMessageRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WebpushConfig: [Webpush
// protocol](https://tools.ietf.org/html/rfc8030) options.
type WebpushConfig struct {
	// Data: Arbitrary key/value payload. If present, it will override
	// google.firebase.fcm.v1.Message.data.
	Data map[string]string `json:"data,omitempty"`

	// FcmOptions: Options for features provided by the FCM SDK for Web.
	FcmOptions *WebpushFcmOptions `json:"fcmOptions,omitempty"`

	// Headers: HTTP headers defined in webpush protocol. Refer to [Webpush
	// protocol](https://tools.ietf.org/html/rfc8030#section-5) for
	// supported headers, e.g. "TTL": "15".
	Headers map[string]string `json:"headers,omitempty"`

	// Notification: Web Notification options as a JSON object. Supports
	// Notification instance properties as defined in [Web Notification
	// API](https://developer.mozilla.org/en-US/docs/Web/API/Notification).
	// If present, "title" and "body" fields override
	// [google.firebase.fcm.v1.Notification.title] and
	// [google.firebase.fcm.v1.Notification.body].
	Notification googleapi.RawMessage `json:"notification,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Data") 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. "Data") 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 *WebpushConfig) MarshalJSON() ([]byte, error) {
	type NoMethod WebpushConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WebpushFcmOptions: Options for features provided by the FCM SDK for
// Web.
type WebpushFcmOptions struct {
	// AnalyticsLabel: Label associated with the message's analytics data.
	AnalyticsLabel string `json:"analyticsLabel,omitempty"`

	// Link: The link to open when the user clicks on the notification. For
	// all URL values, HTTPS is required.
	Link string `json:"link,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnalyticsLabel") 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. "AnalyticsLabel") 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 *WebpushFcmOptions) MarshalJSON() ([]byte, error) {
	type NoMethod WebpushFcmOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "fcm.projects.messages.send":

type ProjectsMessagesSendCall struct {
	s                  *Service
	parentid           string
	sendmessagerequest *SendMessageRequest
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Send: Send a message to specified target (a registration token, topic
// or condition).
func (r *ProjectsMessagesService) Send(parentid string, sendmessagerequest *SendMessageRequest) *ProjectsMessagesSendCall {
	c := &ProjectsMessagesSendCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parentid = parentid
	c.sendmessagerequest = sendmessagerequest
	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 *ProjectsMessagesSendCall) Fields(s ...googleapi.Field) *ProjectsMessagesSendCall {
	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 *ProjectsMessagesSendCall) Context(ctx context.Context) *ProjectsMessagesSendCall {
	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 *ProjectsMessagesSendCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsMessagesSendCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200728")
	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.sendmessagerequest)
	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/{+parent}/messages:send")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parentid,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "fcm.projects.messages.send" call.
// Exactly one of *Message or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Message.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 *ProjectsMessagesSendCall) Do(opts ...googleapi.CallOption) (*Message, 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 := &Message{
		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": "Send a message to specified target (a registration token, topic or condition).",
	//   "flatPath": "v1/projects/{projectsId}/messages:send",
	//   "httpMethod": "POST",
	//   "id": "fcm.projects.messages.send",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. It contains the Firebase project id (i.e. the unique identifier for your Firebase project), in the format of `projects/{project_id}`. For legacy support, the numeric project number with no padding is also supported in the format of `projects/{project_number}`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/messages:send",
	//   "request": {
	//     "$ref": "SendMessageRequest"
	//   },
	//   "response": {
	//     "$ref": "Message"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
