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

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	internaloption "google.golang.org/api/option/internaloption"
	htransport "google.golang.org/api/transport/http"
)

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

const apiId = "firebasedynamiclinks:v1"
const apiName = "firebasedynamiclinks"
const apiVersion = "v1"
const basePath = "https://firebasedynamiclinks.googleapis.com/"
const mtlsBasePath = "https://firebasedynamiclinks.mtls.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...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.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/dynamic-links/link-sh
	// ortener).
	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=com.sample"
	// , [Learn
	// more](https://firebase.google.com/docs/reference/dynamic-links/link-sh
	// ortener).
	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/dynamic-links/link-sh
	// ortener).
	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=com.sample"
	// , [Learn
	// more](https://firebase.google.com/docs/reference/dynamic-links/link-sh
	// ortener).
	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/create-
	// manually).
	AnalyticsInfo *AnalyticsInfo `json:"analyticsInfo,omitempty"`

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

	// DesktopInfo: Desktop related information. See desktop related
	// parameters in the
	// [documentation](https://firebase.google.com/docs/dynamic-links/create-
	// 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/create-
	// 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/create-
	// 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"`

	// UtmContent: Scion content value to be propagated by iSDK to Scion at
	// app-reopen.
	UtmContent string `json:"utmContent,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"`

	// UtmTerm: Scion term value to be propagated by iSDK to Scion at
	// app-reopen.
	UtmTerm string `json:"utmTerm,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. .page.link/, or
	// 2) long FDL. e.g. .page.link/?{query params}, or 3) Invite FDL. e.g.
	// .page.link/i/
	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"`

	// UtmContent: Scion content value to be propagated by iSDK to Scion at
	// app-reopen.
	UtmContent string `json:"utmContent,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"`

	// UtmTerm: Scion term value to be propagated by iSDK to Scion at
	// app-reopen.
	UtmTerm string `json:"utmTerm,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/devguides/collection/and
// roid/v4/campaigns#campaign-params)
type GooglePlayAnalytics struct {
	// Gclid: [AdWords autotagging
	// parameter](https://support.google.com/analytics/answer/1033981?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)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200925")
	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 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.",
	//   "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)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200925")
	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 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.",
	//   "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)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200925")
	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 duration. Metrics include number of clicks, redirects, installs, app 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)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200925")
	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)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200925")
	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"
	//   ]
	// }

}
