// Copyright 2019 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package firebasedynamiclinks provides access to the Firebase Dynamic Links API.
//
// For product documentation, see: https://firebase.google.com/docs/dynamic-links/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/firebasedynamiclinks/v1"
//   ...
//   ctx := context.Background()
//   firebasedynamiclinksService, err := firebasedynamiclinks.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:
//
//   firebasedynamiclinksService, err := firebasedynamiclinks.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, ...)
//   firebasedynamiclinksService, err := firebasedynamiclinks.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package firebasedynamiclinks // import "google.golang.org/api/firebasedynamiclinks/v1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	gensupport "google.golang.org/api/gensupport"
	googleapi "google.golang.org/api/googleapi"
	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 = "firebasedynamiclinks:v1"
const apiName = "firebasedynamiclinks"
const apiVersion = "v1"
const basePath = "https://firebasedynamiclinks.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// View and administer all your Firebase data and settings
	FirebaseScope = "https://www.googleapis.com/auth/firebase"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/firebase",
	)
	// 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.ManagedShortLinks = NewManagedShortLinksService(s)
	s.ShortLinks = NewShortLinksService(s)
	s.V1 = NewV1Service(s)
	return s, nil
}

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

	ManagedShortLinks *ManagedShortLinksService

	ShortLinks *ShortLinksService

	V1 *V1Service
}

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

func NewManagedShortLinksService(s *Service) *ManagedShortLinksService {
	rs := &ManagedShortLinksService{s: s}
	return rs
}

type ManagedShortLinksService struct {
	s *Service
}

func NewShortLinksService(s *Service) *ShortLinksService {
	rs := &ShortLinksService{s: s}
	return rs
}

type ShortLinksService struct {
	s *Service
}

func NewV1Service(s *Service) *V1Service {
	rs := &V1Service{s: s}
	return rs
}

type V1Service struct {
	s *Service
}

// AnalyticsInfo: Tracking parameters supported by Dynamic Link.
type AnalyticsInfo struct {
	// GooglePlayAnalytics: Google Play Campaign Measurements.
	GooglePlayAnalytics *GooglePlayAnalytics `json:"googlePlayAnalytics,omitempty"`

	// ItunesConnectAnalytics: iTunes Connect App Analytics.
	ItunesConnectAnalytics *ITunesConnectAnalytics `json:"itunesConnectAnalytics,omitempty"`

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

// AndroidInfo: Android related attributes to the Dynamic Link.
type AndroidInfo struct {
	// AndroidFallbackLink: Link to open on Android if the app is not
	// installed.
	AndroidFallbackLink string `json:"androidFallbackLink,omitempty"`

	// AndroidLink: If specified, this overrides the ‘link’ parameter on
	// Android.
	AndroidLink string `json:"androidLink,omitempty"`

	// AndroidMinPackageVersionCode: Minimum version code for the Android
	// app. If the installed app’s version
	// code is lower, then the user is taken to the Play Store.
	AndroidMinPackageVersionCode string `json:"androidMinPackageVersionCode,omitempty"`

	// AndroidPackageName: Android package name of the app.
	AndroidPackageName string `json:"androidPackageName,omitempty"`

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

// CreateManagedShortLinkRequest: Request to create a managed Short
// Dynamic Link.
type CreateManagedShortLinkRequest struct {
	// DynamicLinkInfo: Information about the Dynamic Link to be
	// shortened.
	// [Learn
	// more](https://firebase.google.com/docs/reference/dyn
	// amic-links/link-shortener).
	DynamicLinkInfo *DynamicLinkInfo `json:"dynamicLinkInfo,omitempty"`

	// LongDynamicLink: Full long Dynamic Link URL with desired query
	// parameters specified.
	// For
	// example,
	// "https://sample.app.goo.gl/?link=http://www.google.com&apn=co
	// m.sample",
	// [Learn
	// more](https://firebase.google.com/docs/reference/dyn
	// amic-links/link-shortener).
	LongDynamicLink string `json:"longDynamicLink,omitempty"`

	// Name: Link name to associate with the link. It's used for marketer to
	// identify
	// manually-created links in the Firebase
	// console
	// (https://console.firebase.google.com/).
	// Links must be named to be tracked.
	Name string `json:"name,omitempty"`

	// SdkVersion: Google SDK version. Version takes the form
	// "$major.$minor.$patch"
	SdkVersion string `json:"sdkVersion,omitempty"`

	// Suffix: Short Dynamic Link suffix. Optional.
	Suffix *Suffix `json:"suffix,omitempty"`

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

// CreateManagedShortLinkResponse: Response to create a short Dynamic
// Link.
type CreateManagedShortLinkResponse struct {
	// ManagedShortLink: Short Dynamic Link value. e.g.
	// https://abcd.app.goo.gl/wxyz
	ManagedShortLink *ManagedShortLink `json:"managedShortLink,omitempty"`

	// PreviewLink: Preview link to show the link flow chart. (debug info.)
	PreviewLink string `json:"previewLink,omitempty"`

	// Warning: Information about potential warnings on link creation.
	Warning []*DynamicLinkWarning `json:"warning,omitempty"`

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

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

// CreateShortDynamicLinkRequest: Request to create a short Dynamic
// Link.
type CreateShortDynamicLinkRequest struct {
	// DynamicLinkInfo: Information about the Dynamic Link to be
	// shortened.
	// [Learn
	// more](https://firebase.google.com/docs/reference/dyn
	// amic-links/link-shortener).
	DynamicLinkInfo *DynamicLinkInfo `json:"dynamicLinkInfo,omitempty"`

	// LongDynamicLink: Full long Dynamic Link URL with desired query
	// parameters specified.
	// For
	// example,
	// "https://sample.app.goo.gl/?link=http://www.google.com&apn=co
	// m.sample",
	// [Learn
	// more](https://firebase.google.com/docs/reference/dyn
	// amic-links/link-shortener).
	LongDynamicLink string `json:"longDynamicLink,omitempty"`

	// SdkVersion: Google SDK version. Version takes the form
	// "$major.$minor.$patch"
	SdkVersion string `json:"sdkVersion,omitempty"`

	// Suffix: Short Dynamic Link suffix. Optional.
	Suffix *Suffix `json:"suffix,omitempty"`

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

// CreateShortDynamicLinkResponse: Response to create a short Dynamic
// Link.
type CreateShortDynamicLinkResponse struct {
	// PreviewLink: Preview link to show the link flow chart. (debug info.)
	PreviewLink string `json:"previewLink,omitempty"`

	// ShortLink: Short Dynamic Link value. e.g.
	// https://abcd.app.goo.gl/wxyz
	ShortLink string `json:"shortLink,omitempty"`

	// Warning: Information about potential warnings on link creation.
	Warning []*DynamicLinkWarning `json:"warning,omitempty"`

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

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

// DesktopInfo: Desktop related attributes to the Dynamic Link.
type DesktopInfo struct {
	// DesktopFallbackLink: Link to open on desktop.
	DesktopFallbackLink string `json:"desktopFallbackLink,omitempty"`

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

// DeviceInfo: Signals associated with the device making the request.
type DeviceInfo struct {
	// DeviceModelName: Device model name.
	DeviceModelName string `json:"deviceModelName,omitempty"`

	// LanguageCode: Device language code setting.
	LanguageCode string `json:"languageCode,omitempty"`

	// LanguageCodeFromWebview: Device language code setting obtained by
	// executing JavaScript code in
	// WebView.
	LanguageCodeFromWebview string `json:"languageCodeFromWebview,omitempty"`

	// LanguageCodeRaw: Device language code raw setting.
	// iOS does returns language code in different format than iOS
	// WebView.
	// For example WebView returns en_US, but iOS returns en-US.
	// Field below will return raw value returned by iOS.
	LanguageCodeRaw string `json:"languageCodeRaw,omitempty"`

	// ScreenResolutionHeight: Device display resolution height.
	ScreenResolutionHeight int64 `json:"screenResolutionHeight,omitempty,string"`

	// ScreenResolutionWidth: Device display resolution width.
	ScreenResolutionWidth int64 `json:"screenResolutionWidth,omitempty,string"`

	// Timezone: Device timezone setting.
	Timezone string `json:"timezone,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DeviceModelName") 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. "DeviceModelName") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *DeviceInfo) MarshalJSON() ([]byte, error) {
	type NoMethod DeviceInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DynamicLinkEventStat: Dynamic Link event stat.
type DynamicLinkEventStat struct {
	// Count: The number of times this event occurred.
	Count int64 `json:"count,omitempty,string"`

	// Event: Link event.
	//
	// Possible values:
	//   "DYNAMIC_LINK_EVENT_UNSPECIFIED" - Unspecified type.
	//   "CLICK" - Indicates that an FDL is clicked by users.
	//   "REDIRECT" - Indicates that an FDL redirects users to fallback
	// link.
	//   "APP_INSTALL" - Indicates that an FDL triggers an app install from
	// Play store, currently
	// it's impossible to get stats from App store.
	//   "APP_FIRST_OPEN" - Indicates that the app is opened for the first
	// time after an install
	// triggered by FDLs
	//   "APP_RE_OPEN" - Indicates that the app is opened via an FDL for
	// non-first time.
	Event string `json:"event,omitempty"`

	// Platform: Requested platform.
	//
	// Possible values:
	//   "DYNAMIC_LINK_PLATFORM_UNSPECIFIED" - Unspecified platform.
	//   "ANDROID" - Represents Android platform.
	// All apps and browsers on Android are classfied in this category.
	//   "IOS" - Represents iOS platform.
	// All apps and browsers on iOS are classfied in this category.
	//   "DESKTOP" - Represents desktop.
	//   "OTHER" - Platforms are not categorized as Android/iOS/Destop fall
	// into here.
	Platform string `json:"platform,omitempty"`

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

// DynamicLinkInfo: Information about a Dynamic Link.
type DynamicLinkInfo struct {
	// AnalyticsInfo: Parameters used for tracking. See all tracking
	// parameters in
	// the
	// [documentation](https://firebase.google.com/docs/dynamic-links/cre
	// ate-manually).
	AnalyticsInfo *AnalyticsInfo `json:"analyticsInfo,omitempty"`

	// AndroidInfo: Android related information. See Android related
	// parameters in
	// the
	// [documentation](https://firebase.google.com/docs/dynamic-links/cre
	// ate-manually).
	AndroidInfo *AndroidInfo `json:"androidInfo,omitempty"`

	// DesktopInfo: Desktop related information. See desktop related
	// parameters in
	// the
	// [documentation](https://firebase.google.com/docs/dynamic-links/cre
	// ate-manually).
	DesktopInfo *DesktopInfo `json:"desktopInfo,omitempty"`

	// DomainUriPrefix: E.g. https://maps.app.goo.gl,
	// https://maps.page.link, https://g.co/maps
	// More examples can be found in description of getNormalizedUriPrefix
	// in
	// j/c/g/firebase/dynamiclinks/uri/DdlDomain.java
	//
	// Will fallback to dynamic_link_domain is this field is missing
	DomainUriPrefix string `json:"domainUriPrefix,omitempty"`

	// DynamicLinkDomain: Dynamic Links domain that the project owns, e.g.
	// abcd.app.goo.gl
	// [Learn
	// more](https://firebase.google.com/docs/dynamic-
	// links/android/receive) on
	// how to set up Dynamic Link domain associated with your Firebase
	// project.
	//
	// Required if missing domain_uri_prefix.
	DynamicLinkDomain string `json:"dynamicLinkDomain,omitempty"`

	// IosInfo: iOS related information. See iOS related parameters in
	// the
	// [documentation](https://firebase.google.com/docs/dynamic-links/cre
	// ate-manually).
	IosInfo *IosInfo `json:"iosInfo,omitempty"`

	// Link: The link your app will open, You can specify any URL your app
	// can handle.
	// This link must be a well-formatted URL, be properly URL-encoded, and
	// use
	// the HTTP or HTTPS scheme. See 'link' parameters in
	// the
	// [documentation](https://firebase.google.com/docs/dynamic-links/cre
	// ate-manually).
	//
	// Required.
	Link string `json:"link,omitempty"`

	// NavigationInfo: Information of navigation behavior of a Firebase
	// Dynamic Links.
	NavigationInfo *NavigationInfo `json:"navigationInfo,omitempty"`

	// SocialMetaTagInfo: Parameters for social meta tag params.
	// Used to set meta tag data for link previews on social sites.
	SocialMetaTagInfo *SocialMetaTagInfo `json:"socialMetaTagInfo,omitempty"`

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

// DynamicLinkStats: Analytics stats of a Dynamic Link for a given
// timeframe.
type DynamicLinkStats struct {
	// LinkEventStats: Dynamic Link event stats.
	LinkEventStats []*DynamicLinkEventStat `json:"linkEventStats,omitempty"`

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

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

// DynamicLinkWarning: Dynamic Links warning messages.
type DynamicLinkWarning struct {
	// WarningCode: The warning code.
	//
	// Possible values:
	//   "CODE_UNSPECIFIED" - Unknown code.
	//   "NOT_IN_PROJECT_ANDROID_PACKAGE_NAME" - The Android package does
	// not match any in developer's DevConsole project.
	//   "NOT_INTEGER_ANDROID_PACKAGE_MIN_VERSION" - The Android minimum
	// version code has to be a valid integer.
	//   "UNNECESSARY_ANDROID_PACKAGE_MIN_VERSION" - Android package min
	// version param is not needed, e.g. when
	// 'apn' is missing.
	//   "NOT_URI_ANDROID_LINK" - Android link is not a valid URI.
	//   "UNNECESSARY_ANDROID_LINK" - Android link param is not needed, e.g.
	// when param 'al' and 'link' have
	// the same value..
	//   "NOT_URI_ANDROID_FALLBACK_LINK" - Android fallback link is not a
	// valid URI.
	//   "BAD_URI_SCHEME_ANDROID_FALLBACK_LINK" - Android fallback link has
	// an invalid (non http/https) URI scheme.
	//   "NOT_IN_PROJECT_IOS_BUNDLE_ID" - The iOS bundle ID does not match
	// any in developer's DevConsole project.
	//   "NOT_IN_PROJECT_IPAD_BUNDLE_ID" - The iPad bundle ID does not match
	// any in developer's DevConsole project.
	//   "UNNECESSARY_IOS_URL_SCHEME" - iOS URL scheme is not needed, e.g.
	// when 'ibi' are 'ipbi' are all missing.
	//   "NOT_NUMERIC_IOS_APP_STORE_ID" - iOS app store ID format is
	// incorrect, e.g. not numeric.
	//   "UNNECESSARY_IOS_APP_STORE_ID" - iOS app store ID is not needed.
	//   "NOT_URI_IOS_FALLBACK_LINK" - iOS fallback link is not a valid URI.
	//   "BAD_URI_SCHEME_IOS_FALLBACK_LINK" - iOS fallback link has an
	// invalid (non http/https) URI scheme.
	//   "NOT_URI_IPAD_FALLBACK_LINK" - iPad fallback link is not a valid
	// URI.
	//   "BAD_URI_SCHEME_IPAD_FALLBACK_LINK" - iPad fallback link has an
	// invalid (non http/https) URI scheme.
	//   "BAD_DEBUG_PARAM" - Debug param format is incorrect.
	//   "BAD_AD_PARAM" - isAd param format is incorrect.
	//   "DEPRECATED_PARAM" - Indicates a certain param is deprecated.
	//   "UNRECOGNIZED_PARAM" - Indicates certain paramater is not
	// recognized.
	//   "TOO_LONG_PARAM" - Indicates certain paramater is too long.
	//   "NOT_URI_SOCIAL_IMAGE_LINK" - Social meta tag image link is not a
	// valid URI.
	//   "BAD_URI_SCHEME_SOCIAL_IMAGE_LINK" - Social meta tag image link has
	// an invalid (non http/https) URI scheme.
	//   "NOT_URI_SOCIAL_URL"
	//   "BAD_URI_SCHEME_SOCIAL_URL"
	//   "LINK_LENGTH_TOO_LONG" - Dynamic Link URL length is too long.
	//   "LINK_WITH_FRAGMENTS" - Dynamic Link URL contains fragments.
	//   "NOT_MATCHING_IOS_BUNDLE_ID_AND_STORE_ID" - The iOS bundle ID does
	// not match with the given iOS store ID.
	WarningCode string `json:"warningCode,omitempty"`

	// WarningDocumentLink: The document describing the warning, and helps
	// resolve.
	WarningDocumentLink string `json:"warningDocumentLink,omitempty"`

	// WarningMessage: The warning message to help developers improve their
	// requests.
	WarningMessage string `json:"warningMessage,omitempty"`

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

// GetIosPostInstallAttributionRequest: Request for iSDK to execute
// strong match flow for post-install attribution.
// This is meant for iOS requests only. Requests from other platforms
// will
// not be honored.
type GetIosPostInstallAttributionRequest struct {
	// AppInstallationTime: App installation epoch time
	// (https://en.wikipedia.org/wiki/Unix_time).
	// This is a client signal for a more accurate weak match.
	AppInstallationTime int64 `json:"appInstallationTime,omitempty,string"`

	// BundleId: APP bundle ID.
	BundleId string `json:"bundleId,omitempty"`

	// Device: Device information.
	Device *DeviceInfo `json:"device,omitempty"`

	// IosVersion: iOS version, ie: 9.3.5.
	// Consider adding "build".
	IosVersion string `json:"iosVersion,omitempty"`

	// RetrievalMethod: App post install attribution retrieval information.
	// Disambiguates
	// mechanism (iSDK or developer invoked) to retrieve payload
	// from
	// clicked link.
	//
	// Possible values:
	//   "UNKNOWN_PAYLOAD_RETRIEVAL_METHOD" - Unknown method.
	//   "IMPLICIT_WEAK_MATCH" - iSDK performs a server lookup by device
	// fingerprint in the background
	// when app is first-opened; no API called by developer.
	//   "EXPLICIT_WEAK_MATCH" - iSDK performs a server lookup by device
	// fingerprint upon a dev API call.
	//   "EXPLICIT_STRONG_AFTER_WEAK_MATCH" - iSDK performs a strong match
	// only if weak match is found upon a dev
	// API call.
	RetrievalMethod string `json:"retrievalMethod,omitempty"`

	// SdkVersion: Google SDK version. Version takes the form
	// "$major.$minor.$patch"
	SdkVersion string `json:"sdkVersion,omitempty"`

	// UniqueMatchLinkToCheck: Possible unique matched link that server need
	// to check before performing
	// fingerprint match. If passed link is short server need to expand the
	// link.
	// If link is long server need to vslidate the link.
	UniqueMatchLinkToCheck string `json:"uniqueMatchLinkToCheck,omitempty"`

	// VisualStyle: Strong match page information. Disambiguates between
	// default UI and
	// custom page to present when strong match succeeds/fails to find
	// cookie.
	//
	// Possible values:
	//   "UNKNOWN_VISUAL_STYLE" - Unknown style.
	//   "DEFAULT_STYLE" - Default style.
	//   "CUSTOM_STYLE" - Custom style.
	VisualStyle string `json:"visualStyle,omitempty"`

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

// GetIosPostInstallAttributionResponse: Response for iSDK to execute
// strong match flow for post-install attribution.
type GetIosPostInstallAttributionResponse struct {
	// AppMinimumVersion: The minimum version for app, specified by dev
	// through ?imv= parameter.
	// Return to iSDK to allow app to evaluate if current version meets
	// this.
	AppMinimumVersion string `json:"appMinimumVersion,omitempty"`

	// AttributionConfidence: The confidence of the returned attribution.
	//
	// Possible values:
	//   "UNKNOWN_ATTRIBUTION_CONFIDENCE" - Unset.
	//   "WEAK" - Weak confidence, more than one matching link found or link
	// suspected to
	// be false positive
	//   "DEFAULT" - Default confidence, match based on fingerprint
	//   "UNIQUE" - Unique confidence, match based on "unique match link to
	// check" or other
	// means
	AttributionConfidence string `json:"attributionConfidence,omitempty"`

	// DeepLink: The deep-link attributed post-install via one of several
	// techniques
	// (fingerprint, copy unique).
	DeepLink string `json:"deepLink,omitempty"`

	// ExternalBrowserDestinationLink: User-agent specific custom-scheme
	// URIs for iSDK to open. This will be set
	// according to the user-agent tha the click was originally made in.
	// There is
	// no Safari-equivalent custom-scheme open URLs.
	// ie: googlechrome://www.example.com
	// ie: firefox://open-url?url=http://www.example.com
	// ie: opera-http://example.com
	ExternalBrowserDestinationLink string `json:"externalBrowserDestinationLink,omitempty"`

	// FallbackLink: The link to navigate to update the app if min version
	// is not met.
	// This is either (in order): 1) fallback link (from ?ifl= parameter,
	// if
	// specified by developer) or 2) AppStore URL (from ?isi= parameter,
	// if
	// specified), or 3) the payload link (from required link= parameter).
	FallbackLink string `json:"fallbackLink,omitempty"`

	// InvitationId: Invitation ID attributed post-install via one of
	// several techniques
	// (fingerprint, copy unique).
	InvitationId string `json:"invitationId,omitempty"`

	// IsStrongMatchExecutable: Instruction for iSDK to attemmpt to perform
	// strong match. For instance,
	// if browser does not support/allow cookie or outside of support
	// browsers,
	// this will be false.
	IsStrongMatchExecutable bool `json:"isStrongMatchExecutable,omitempty"`

	// MatchMessage: Describes why match failed, ie: "discarded due to low
	// confidence".
	// This message will be publicly visible.
	MatchMessage string `json:"matchMessage,omitempty"`

	// RequestIpVersion: Which IP version the request was made from.
	//
	// Possible values:
	//   "UNKNOWN_IP_VERSION" - Unset.
	//   "IP_V4" - Request made from an IPv4 IP address.
	//   "IP_V6" - Request made from an IPv6 IP address.
	RequestIpVersion string `json:"requestIpVersion,omitempty"`

	// RequestedLink: Entire FDL (short or long) attributed post-install via
	// one of several
	// techniques (fingerprint, copy unique).
	RequestedLink string `json:"requestedLink,omitempty"`

	// ResolvedLink: The entire FDL, expanded from a short link. It is the
	// same as the
	// requested_link, if it is long. Parameters from this should not
	// be
	// used directly (ie: server can default utm_[campaign|medium|source]
	// to a value when requested_link lack them, server determine the
	// best
	// fallback_link when requested_link specifies >1 fallback links).
	ResolvedLink string `json:"resolvedLink,omitempty"`

	// UtmCampaign: Scion campaign value to be propagated by iSDK to Scion
	// at post-install.
	UtmCampaign string `json:"utmCampaign,omitempty"`

	// UtmMedium: Scion medium value to be propagated by iSDK to Scion at
	// post-install.
	UtmMedium string `json:"utmMedium,omitempty"`

	// UtmSource: Scion source value to be propagated by iSDK to Scion at
	// post-install.
	UtmSource string `json:"utmSource,omitempty"`

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

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

// GetIosReopenAttributionRequest: Request for iSDK to get reopen
// attribution for app universal link open
// deeplinking. This endpoint is meant for only iOS requests.
type GetIosReopenAttributionRequest struct {
	// BundleId: APP bundle ID.
	BundleId string `json:"bundleId,omitempty"`

	// RequestedLink: FDL link to be verified from an app universal link
	// open.
	// The FDL link can be one of:
	// 1) short FDL.
	// e.g. <app_code>.page.link/<ddl_id>, or
	// 2) long FDL.
	// e.g. <app_code>.page.link/?{query params}, or
	// 3) Invite FDL.
	// e.g. <app_code>.page.link/i/<invite_id_or_alias>
	RequestedLink string `json:"requestedLink,omitempty"`

	// SdkVersion: Google SDK version. Version takes the form
	// "$major.$minor.$patch"
	SdkVersion string `json:"sdkVersion,omitempty"`

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

// GetIosReopenAttributionResponse: Response for iSDK to get reopen
// attribution for app universal link open
// deeplinking. This endpoint is meant for only iOS requests.
type GetIosReopenAttributionResponse struct {
	// DeepLink: The deep-link attributed the app universal link open. For
	// both regular
	// FDL links and invite FDL links.
	DeepLink string `json:"deepLink,omitempty"`

	// InvitationId: Optional invitation ID, for only invite typed requested
	// FDL links.
	InvitationId string `json:"invitationId,omitempty"`

	// IosMinAppVersion: FDL input value of the "&imv=" parameter, minimum
	// app version to be
	// returned to Google Firebase SDK running on iOS-9.
	IosMinAppVersion string `json:"iosMinAppVersion,omitempty"`

	// ResolvedLink: The entire FDL, expanded from a short link. It is the
	// same as the
	// requested_link, if it is long.
	ResolvedLink string `json:"resolvedLink,omitempty"`

	// UtmCampaign: Scion campaign value to be propagated by iSDK to Scion
	// at app-reopen.
	UtmCampaign string `json:"utmCampaign,omitempty"`

	// UtmMedium: Scion medium value to be propagated by iSDK to Scion at
	// app-reopen.
	UtmMedium string `json:"utmMedium,omitempty"`

	// UtmSource: Scion source value to be propagated by iSDK to Scion at
	// app-reopen.
	UtmSource string `json:"utmSource,omitempty"`

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

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

// GooglePlayAnalytics: Parameters for Google Play Campaign
// Measurements.
// [Learn
// more](https://developers.google.com/analytics/dev
// guides/collection/android/v4/campaigns#campaign-params)
type GooglePlayAnalytics struct {
	// Gclid: [AdWords
	// autotagging
	// parameter](https://support.google.com/analytics/answer/103
	// 3981?hl=en); used
	// to measure Google AdWords ads. This value is generated dynamically
	// and
	// should never be modified.
	Gclid string `json:"gclid,omitempty"`

	// UtmCampaign: Campaign name; used for keyword analysis to identify a
	// specific product
	// promotion or strategic campaign.
	UtmCampaign string `json:"utmCampaign,omitempty"`

	// UtmContent: Campaign content; used for A/B testing and
	// content-targeted ads to
	// differentiate ads or links that point to the same URL.
	UtmContent string `json:"utmContent,omitempty"`

	// UtmMedium: Campaign medium; used to identify a medium such as email
	// or cost-per-click.
	UtmMedium string `json:"utmMedium,omitempty"`

	// UtmSource: Campaign source; used to identify a search engine,
	// newsletter, or other
	// source.
	UtmSource string `json:"utmSource,omitempty"`

	// UtmTerm: Campaign term; used with paid search to supply the keywords
	// for ads.
	UtmTerm string `json:"utmTerm,omitempty"`

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

// ITunesConnectAnalytics: Parameters for iTunes Connect App Analytics.
type ITunesConnectAnalytics struct {
	// At: Affiliate token used to create affiliate-coded links.
	At string `json:"at,omitempty"`

	// Ct: Campaign text that developers can optionally add to any link in
	// order to
	// track sales from a specific marketing campaign.
	Ct string `json:"ct,omitempty"`

	// Mt: iTune media types, including music, podcasts, audiobooks and so
	// on.
	Mt string `json:"mt,omitempty"`

	// Pt: Provider token that enables analytics for Dynamic Links from
	// within iTunes
	// Connect.
	Pt string `json:"pt,omitempty"`

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

// IosInfo: iOS related attributes to the Dynamic Link..
type IosInfo struct {
	// IosAppStoreId: iOS App Store ID.
	IosAppStoreId string `json:"iosAppStoreId,omitempty"`

	// IosBundleId: iOS bundle ID of the app.
	IosBundleId string `json:"iosBundleId,omitempty"`

	// IosCustomScheme: Custom (destination) scheme to use for iOS. By
	// default, we’ll use the
	// bundle ID as the custom scheme. Developer can override this behavior
	// using
	// this param.
	IosCustomScheme string `json:"iosCustomScheme,omitempty"`

	// IosFallbackLink: Link to open on iOS if the app is not installed.
	IosFallbackLink string `json:"iosFallbackLink,omitempty"`

	// IosIpadBundleId: iPad bundle ID of the app.
	IosIpadBundleId string `json:"iosIpadBundleId,omitempty"`

	// IosIpadFallbackLink: If specified, this overrides the
	// ios_fallback_link value on iPads.
	IosIpadFallbackLink string `json:"iosIpadFallbackLink,omitempty"`

	// IosMinimumVersion: iOS minimum version.
	IosMinimumVersion string `json:"iosMinimumVersion,omitempty"`

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

// ManagedShortLink: Managed Short Link.
type ManagedShortLink struct {
	// CreationTime: Creation timestamp of the short link.
	CreationTime string `json:"creationTime,omitempty"`

	// FlaggedAttribute: Attributes that have been flagged about this short
	// url.
	//
	// Possible values:
	//   "UNSPECIFIED_ATTRIBUTE" - Indicates that no attributes were found
	// for this short url.
	//   "SPAM" - Indicates that short url has been flagged by AbuseIAm team
	// as spam.
	FlaggedAttribute []string `json:"flaggedAttribute,omitempty"`

	// Info: Full Dyamic Link info
	Info *DynamicLinkInfo `json:"info,omitempty"`

	// Link: Short durable link url, for example,
	// "https://sample.app.goo.gl/xyz123".
	//
	// Required.
	Link string `json:"link,omitempty"`

	// LinkName: Link name defined by the creator.
	//
	// Required.
	LinkName string `json:"linkName,omitempty"`

	// Visibility: Visibility status of link.
	//
	// Possible values:
	//   "UNSPECIFIED_VISIBILITY" - Visibility of the link is not specified.
	//   "UNARCHIVED" - Link created in console and should be shown in
	// console.
	//   "ARCHIVED" - Link created in console and should not be shown in
	// console (but can
	// be shown in the console again if it is unarchived).
	//   "NEVER_SHOWN" - Link created outside of console and should never be
	// shown in console.
	Visibility string `json:"visibility,omitempty"`

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

// NavigationInfo: Information of navigation behavior.
type NavigationInfo struct {
	// EnableForcedRedirect: If this option is on, FDL click will be forced
	// to redirect rather than
	// show an interstitial page.
	EnableForcedRedirect bool `json:"enableForcedRedirect,omitempty"`

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

// SocialMetaTagInfo: Parameters for social meta tag params.
// Used to set meta tag data for link previews on social sites.
type SocialMetaTagInfo struct {
	// SocialDescription: A short description of the link. Optional.
	SocialDescription string `json:"socialDescription,omitempty"`

	// SocialImageLink: An image url string. Optional.
	SocialImageLink string `json:"socialImageLink,omitempty"`

	// SocialTitle: Title to be displayed. Optional.
	SocialTitle string `json:"socialTitle,omitempty"`

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

// Suffix: Short Dynamic Link suffix.
type Suffix struct {
	// CustomSuffix: Only applies to Option.CUSTOM.
	CustomSuffix string `json:"customSuffix,omitempty"`

	// Option: Suffix option.
	//
	// Possible values:
	//   "OPTION_UNSPECIFIED" - The suffix option is not specified, performs
	// as UNGUESSABLE .
	//   "UNGUESSABLE" - Short Dynamic Link suffix is a base62 [0-9A-Za-z]
	// encoded string of
	// a random generated 96 bit random number, which has a length of 17
	// chars.
	// For example, "nlAR8U4SlKRZw1cb2".
	// It prevents other people from guessing and crawling short Dynamic
	// Links
	// that contain personal identifiable information.
	//   "SHORT" - Short Dynamic Link suffix is a base62 [0-9A-Za-z] string
	// starting with a
	// length of 4 chars. the length will increase when all the space
	// is
	// occupied.
	//   "CUSTOM" - Custom DDL suffix is a client specified string, for
	// example,
	// "buy2get1free".
	// NOTE: custom suffix should only be available to managed short
	// link
	// creation
	Option string `json:"option,omitempty"`

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

// method id "firebasedynamiclinks.managedShortLinks.create":

type ManagedShortLinksCreateCall struct {
	s                             *Service
	createmanagedshortlinkrequest *CreateManagedShortLinkRequest
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// Create: Creates a managed short Dynamic Link given either a valid
// long Dynamic Link
// or details such as Dynamic Link domain, Android and iOS app
// information.
// The created short Dynamic Link will not expire.
//
// This differs from CreateShortDynamicLink in the following ways:
//   - The request will also contain a name for the link (non unique
// name
//     for the front end).
//   - The response must be authenticated with an auth token (generated
// with
//     the admin service account).
//   - The link will appear in the FDL list of links in the console
// front end.
//
// The Dynamic Link domain in the request must be owned by
// requester's
// Firebase project.
func (r *ManagedShortLinksService) Create(createmanagedshortlinkrequest *CreateManagedShortLinkRequest) *ManagedShortLinksCreateCall {
	c := &ManagedShortLinksCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.createmanagedshortlinkrequest = createmanagedshortlinkrequest
	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 *ManagedShortLinksCreateCall) Fields(s ...googleapi.Field) *ManagedShortLinksCreateCall {
	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 *ManagedShortLinksCreateCall) Context(ctx context.Context) *ManagedShortLinksCreateCall {
	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 *ManagedShortLinksCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ManagedShortLinksCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	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.createmanagedshortlinkrequest)
	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/managedShortLinks:create")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "firebasedynamiclinks.managedShortLinks.create" call.
// Exactly one of *CreateManagedShortLinkResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *CreateManagedShortLinkResponse.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 *ManagedShortLinksCreateCall) Do(opts ...googleapi.CallOption) (*CreateManagedShortLinkResponse, 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 := &CreateManagedShortLinkResponse{
		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": "Creates a managed short Dynamic Link given either a valid long Dynamic Link\nor details such as Dynamic Link domain, Android and iOS app information.\nThe created short Dynamic Link will not expire.\n\nThis differs from CreateShortDynamicLink in the following ways:\n  - The request will also contain a name for the link (non unique name\n    for the front end).\n  - The response must be authenticated with an auth token (generated with\n    the admin service account).\n  - The link will appear in the FDL list of links in the console front end.\n\nThe Dynamic Link domain in the request must be owned by requester's\nFirebase project.",
	//   "flatPath": "v1/managedShortLinks:create",
	//   "httpMethod": "POST",
	//   "id": "firebasedynamiclinks.managedShortLinks.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/managedShortLinks:create",
	//   "request": {
	//     "$ref": "CreateManagedShortLinkRequest"
	//   },
	//   "response": {
	//     "$ref": "CreateManagedShortLinkResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/firebase"
	//   ]
	// }

}

// method id "firebasedynamiclinks.shortLinks.create":

type ShortLinksCreateCall struct {
	s                             *Service
	createshortdynamiclinkrequest *CreateShortDynamicLinkRequest
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// Create: Creates a short Dynamic Link given either a valid long
// Dynamic Link or
// details such as Dynamic Link domain, Android and iOS app
// information.
// The created short Dynamic Link will not expire.
//
// Repeated calls with the same long Dynamic Link or Dynamic Link
// information
// will produce the same short Dynamic Link.
//
// The Dynamic Link domain in the request must be owned by
// requester's
// Firebase project.
func (r *ShortLinksService) Create(createshortdynamiclinkrequest *CreateShortDynamicLinkRequest) *ShortLinksCreateCall {
	c := &ShortLinksCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.createshortdynamiclinkrequest = createshortdynamiclinkrequest
	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 *ShortLinksCreateCall) Fields(s ...googleapi.Field) *ShortLinksCreateCall {
	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 *ShortLinksCreateCall) Context(ctx context.Context) *ShortLinksCreateCall {
	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 *ShortLinksCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ShortLinksCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	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.createshortdynamiclinkrequest)
	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/shortLinks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "firebasedynamiclinks.shortLinks.create" call.
// Exactly one of *CreateShortDynamicLinkResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *CreateShortDynamicLinkResponse.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 *ShortLinksCreateCall) Do(opts ...googleapi.CallOption) (*CreateShortDynamicLinkResponse, 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 := &CreateShortDynamicLinkResponse{
		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": "Creates a short Dynamic Link given either a valid long Dynamic Link or\ndetails such as Dynamic Link domain, Android and iOS app information.\nThe created short Dynamic Link will not expire.\n\nRepeated calls with the same long Dynamic Link or Dynamic Link information\nwill produce the same short Dynamic Link.\n\nThe Dynamic Link domain in the request must be owned by requester's\nFirebase project.",
	//   "flatPath": "v1/shortLinks",
	//   "httpMethod": "POST",
	//   "id": "firebasedynamiclinks.shortLinks.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/shortLinks",
	//   "request": {
	//     "$ref": "CreateShortDynamicLinkRequest"
	//   },
	//   "response": {
	//     "$ref": "CreateShortDynamicLinkResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/firebase"
	//   ]
	// }

}

// method id "firebasedynamiclinks.getLinkStats":

type V1GetLinkStatsCall struct {
	s            *Service
	dynamicLink  string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetLinkStats: Fetches analytics stats of a short Dynamic Link for a
// given
// duration. Metrics include number of clicks, redirects, installs,
// app first opens, and app reopens.
func (r *V1Service) GetLinkStats(dynamicLink string) *V1GetLinkStatsCall {
	c := &V1GetLinkStatsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.dynamicLink = dynamicLink
	return c
}

// DurationDays sets the optional parameter "durationDays": The span of
// time requested in days.
func (c *V1GetLinkStatsCall) DurationDays(durationDays int64) *V1GetLinkStatsCall {
	c.urlParams_.Set("durationDays", fmt.Sprint(durationDays))
	return c
}

// SdkVersion sets the optional parameter "sdkVersion": Google SDK
// version. Version takes the form "$major.$minor.$patch"
func (c *V1GetLinkStatsCall) SdkVersion(sdkVersion string) *V1GetLinkStatsCall {
	c.urlParams_.Set("sdkVersion", sdkVersion)
	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 *V1GetLinkStatsCall) Fields(s ...googleapi.Field) *V1GetLinkStatsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *V1GetLinkStatsCall) IfNoneMatch(entityTag string) *V1GetLinkStatsCall {
	c.ifNoneMatch_ = entityTag
	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 *V1GetLinkStatsCall) Context(ctx context.Context) *V1GetLinkStatsCall {
	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 *V1GetLinkStatsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *V1GetLinkStatsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{dynamicLink}/linkStats")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"dynamicLink": c.dynamicLink,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "firebasedynamiclinks.getLinkStats" call.
// Exactly one of *DynamicLinkStats or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *DynamicLinkStats.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 *V1GetLinkStatsCall) Do(opts ...googleapi.CallOption) (*DynamicLinkStats, 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 := &DynamicLinkStats{
		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": "Fetches analytics stats of a short Dynamic Link for a given\nduration. Metrics include number of clicks, redirects, installs,\napp first opens, and app reopens.",
	//   "flatPath": "v1/{dynamicLink}/linkStats",
	//   "httpMethod": "GET",
	//   "id": "firebasedynamiclinks.getLinkStats",
	//   "parameterOrder": [
	//     "dynamicLink"
	//   ],
	//   "parameters": {
	//     "durationDays": {
	//       "description": "The span of time requested in days.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "dynamicLink": {
	//       "description": "Dynamic Link URL. e.g. https://abcd.app.goo.gl/wxyz",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sdkVersion": {
	//       "description": "Google SDK version. Version takes the form \"$major.$minor.$patch\"",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{dynamicLink}/linkStats",
	//   "response": {
	//     "$ref": "DynamicLinkStats"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/firebase"
	//   ]
	// }

}

// method id "firebasedynamiclinks.installAttribution":

type V1InstallAttributionCall struct {
	s                                   *Service
	getiospostinstallattributionrequest *GetIosPostInstallAttributionRequest
	urlParams_                          gensupport.URLParams
	ctx_                                context.Context
	header_                             http.Header
}

// InstallAttribution: Get iOS strong/weak-match info for post-install
// attribution.
func (r *V1Service) InstallAttribution(getiospostinstallattributionrequest *GetIosPostInstallAttributionRequest) *V1InstallAttributionCall {
	c := &V1InstallAttributionCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.getiospostinstallattributionrequest = getiospostinstallattributionrequest
	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 *V1InstallAttributionCall) Fields(s ...googleapi.Field) *V1InstallAttributionCall {
	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 *V1InstallAttributionCall) Context(ctx context.Context) *V1InstallAttributionCall {
	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 *V1InstallAttributionCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *V1InstallAttributionCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	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.getiospostinstallattributionrequest)
	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/installAttribution")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "firebasedynamiclinks.installAttribution" call.
// Exactly one of *GetIosPostInstallAttributionResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GetIosPostInstallAttributionResponse.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 *V1InstallAttributionCall) Do(opts ...googleapi.CallOption) (*GetIosPostInstallAttributionResponse, 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 := &GetIosPostInstallAttributionResponse{
		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": "Get iOS strong/weak-match info for post-install attribution.",
	//   "flatPath": "v1/installAttribution",
	//   "httpMethod": "POST",
	//   "id": "firebasedynamiclinks.installAttribution",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/installAttribution",
	//   "request": {
	//     "$ref": "GetIosPostInstallAttributionRequest"
	//   },
	//   "response": {
	//     "$ref": "GetIosPostInstallAttributionResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/firebase"
	//   ]
	// }

}

// method id "firebasedynamiclinks.reopenAttribution":

type V1ReopenAttributionCall struct {
	s                              *Service
	getiosreopenattributionrequest *GetIosReopenAttributionRequest
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// ReopenAttribution: Get iOS reopen attribution for app universal link
// open deeplinking.
func (r *V1Service) ReopenAttribution(getiosreopenattributionrequest *GetIosReopenAttributionRequest) *V1ReopenAttributionCall {
	c := &V1ReopenAttributionCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.getiosreopenattributionrequest = getiosreopenattributionrequest
	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 *V1ReopenAttributionCall) Fields(s ...googleapi.Field) *V1ReopenAttributionCall {
	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 *V1ReopenAttributionCall) Context(ctx context.Context) *V1ReopenAttributionCall {
	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 *V1ReopenAttributionCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *V1ReopenAttributionCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	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.getiosreopenattributionrequest)
	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/reopenAttribution")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "firebasedynamiclinks.reopenAttribution" call.
// Exactly one of *GetIosReopenAttributionResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GetIosReopenAttributionResponse.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 *V1ReopenAttributionCall) Do(opts ...googleapi.CallOption) (*GetIosReopenAttributionResponse, 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 := &GetIosReopenAttributionResponse{
		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": "Get iOS reopen attribution for app universal link open deeplinking.",
	//   "flatPath": "v1/reopenAttribution",
	//   "httpMethod": "POST",
	//   "id": "firebasedynamiclinks.reopenAttribution",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/reopenAttribution",
	//   "request": {
	//     "$ref": "GetIosReopenAttributionRequest"
	//   },
	//   "response": {
	//     "$ref": "GetIosReopenAttributionResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/firebase"
	//   ]
	// }

}
