// 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/"

// 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))
	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/no
	// tifications#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/b
	// ase/+/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/b
	// ase/+/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/b
	// ase/+/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-buff
	// ers/docs/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/notificati
	// ons/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-use
	// r/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/refe
	// rence/fcm/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/
	// docs/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/
	// android/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/usernotific
	// ations/setting_up_a_remote_notification_server/sending_notification_re
	// quests_to_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/usernotificat
	// ions/setting_up_a_remote_notification_server/generating_a_remote_notif
	// ication).
	// 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
	// /master/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/doc
	// s/reference/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/doc
	// s/reference/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/Not
	// ification). 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/20200617")
	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\nor 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\nfor your Firebase project), in the format of `projects/{project_id}`.\nFor legacy support, the numeric project number with no padding is also\nsupported 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"
	//   ]
	// }

}
