// 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"
	htransport "google.golang.org/api/transport/http"
)

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

const apiId = "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...)
	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.
//
// 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/1.11.0 gdcl/20200109")
	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"
	//   ]
	// }

}
