// 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 surveys provides access to the Surveys API.
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/surveys/v2"
//   ...
//   ctx := context.Background()
//   surveysService, err := surveys.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
//
// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes:
//
//   surveysService, err := surveys.NewService(ctx, option.WithScopes(surveys.UserinfoEmailScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   surveysService, err := surveys.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, ...)
//   surveysService, err := surveys.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package surveys // import "google.golang.org/api/surveys/v2"

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

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

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

const apiId = "surveys:v2"
const apiName = "surveys"
const apiVersion = "v2"
const basePath = "https://www.googleapis.com/surveys/v2/"

// OAuth2 scopes used by this API.
const (
	// View and manage your surveys and results
	SurveysScope = "https://www.googleapis.com/auth/surveys"

	// View your surveys and survey results
	SurveysReadonlyScope = "https://www.googleapis.com/auth/surveys.readonly"

	// View your email address
	UserinfoEmailScope = "https://www.googleapis.com/auth/userinfo.email"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/surveys",
		"https://www.googleapis.com/auth/surveys.readonly",
		"https://www.googleapis.com/auth/userinfo.email",
	)
	// 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.Results = NewResultsService(s)
	s.Surveys = NewSurveysService(s)
	return s, nil
}

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

	Results *ResultsService

	Surveys *SurveysService
}

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

func NewResultsService(s *Service) *ResultsService {
	rs := &ResultsService{s: s}
	return rs
}

type ResultsService struct {
	s *Service
}

func NewSurveysService(s *Service) *SurveysService {
	rs := &SurveysService{s: s}
	return rs
}

type SurveysService struct {
	s *Service
}

type FieldMask struct {
	Fields []*FieldMask `json:"fields,omitempty"`

	Id int64 `json:"id,omitempty"`

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

type PageInfo struct {
	ResultPerPage int64 `json:"resultPerPage,omitempty"`

	StartIndex int64 `json:"startIndex,omitempty"`

	TotalResults int64 `json:"totalResults,omitempty"`

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

type ResultsGetRequest struct {
	ResultMask *ResultsMask `json:"resultMask,omitempty"`

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

type ResultsMask struct {
	Fields []*FieldMask `json:"fields,omitempty"`

	Projection string `json:"projection,omitempty"`

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

// Survey: Representation of an individual survey object.
type Survey struct {
	// Audience: Targeting-criteria message containing demographic
	// information
	Audience *SurveyAudience `json:"audience,omitempty"`

	// Cost: Cost to run the survey and collect the necessary number of
	// responses.
	Cost *SurveyCost `json:"cost,omitempty"`

	// CustomerData: Additional information to store on behalf of the API
	// consumer and associate with this question. This binary blob is
	// treated as opaque. This field is limited to 64K bytes.
	CustomerData string `json:"customerData,omitempty"`

	// Description: Text description of the survey.
	Description string `json:"description,omitempty"`

	// Owners: List of email addresses for survey owners. Must contain at
	// least the address of the user making the API call.
	Owners []string `json:"owners,omitempty"`

	// Questions: List of questions defining the survey.
	Questions []*SurveyQuestion `json:"questions,omitempty"`

	// RejectionReason: Reason for the survey being rejected. Only present
	// if the survey state is rejected.
	RejectionReason *SurveyRejection `json:"rejectionReason,omitempty"`

	// State: State that the survey is in.
	State string `json:"state,omitempty"`

	// SurveyUrlId: Unique survey ID, that is viewable in the URL of the
	// Survey Creator UI
	SurveyUrlId string `json:"surveyUrlId,omitempty"`

	// Title: Optional name that will be given to the survey.
	Title string `json:"title,omitempty"`

	// WantedResponseCount: Number of responses desired for the survey.
	WantedResponseCount int64 `json:"wantedResponseCount,omitempty"`

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

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

// SurveyAudience: Specifications for the target audience of a survey
// run through the API.
type SurveyAudience struct {
	// Ages: Optional list of age buckets to target. Supported age buckets
	// are: ['18-24', '25-34', '35-44', '45-54', '55-64', '65+']
	Ages []string `json:"ages,omitempty"`

	// Country: Required country code that surveys should be targeted to.
	// Accepts standard ISO 3166-1 2 character language codes. For instance,
	// 'US' for the United States, and 'GB' for the United Kingdom.
	Country string `json:"country,omitempty"`

	// CountrySubdivision: Country subdivision (states/provinces/etc) that
	// surveys should be targeted to. For all countries except GB,
	// ISO-3166-2 subdivision code is required (eg. 'US-OH' for Ohio, United
	// States). For GB, NUTS 1 statistical region codes for the United
	// Kingdom is required (eg. 'UK-UKC' for North East England).
	CountrySubdivision string `json:"countrySubdivision,omitempty"`

	// Gender: Optional gender to target.
	Gender string `json:"gender,omitempty"`

	// Languages: Language code that surveys should be targeted to. For
	// instance, 'en-US'. Surveys may target bilingual users by specifying a
	// list of language codes (for example, 'de' and 'en-US'). In that case,
	// all languages will be used for targeting users but the survey content
	// (which is displayed) must match the first language listed. Accepts
	// standard BCP47 language codes. See specification.
	Languages []string `json:"languages,omitempty"`

	// PopulationSource: Online population source where the respondents are
	// sampled from.
	PopulationSource string `json:"populationSource,omitempty"`

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

// SurveyCost: Message defining the cost to run a given survey through
// API.
type SurveyCost struct {
	// CostPerResponseNanos: Cost per survey response in nano units of the
	// given currency. To get the total cost for a survey, multiply this
	// value by wanted_response_count.
	CostPerResponseNanos int64 `json:"costPerResponseNanos,omitempty,string"`

	// CurrencyCode: Currency code that the cost is given in.
	CurrencyCode string `json:"currencyCode,omitempty"`

	// MaxCostPerResponseNanos: *Deprecated* Threshold to start a survey
	// automatically if the quoted price is at most this value. When a
	// survey has a Screener (threshold) question, it must go through an
	// incidence pricing test to determine the final cost per response.
	// Typically you will have to make a followup call to start the survey
	// giving the final computed cost per response. If the survey has no
	// threshold_answers, setting this property will return an error. By
	// specifying this property, you indicate the max price per response you
	// are willing to pay in advance of the incidence test. If the price
	// turns out to be lower than the specified value, the survey will begin
	// immediately and you will be charged at the rate determined by the
	// incidence pricing test. If the price turns out to be greater than the
	// specified value the survey will not be started and you will instead
	// be notified what price was determined by the incidence test. At that
	// point, you must raise the value of this property to be greater than
	// or equal to that cost before attempting to start the survey again.
	// This will immediately start the survey as long the incidence test was
	// run within the last 21 days. This will no longer be available after
	// June 2018.
	MaxCostPerResponseNanos int64 `json:"maxCostPerResponseNanos,omitempty,string"`

	// Nanos: Cost of survey in nano units of the given currency. DEPRECATED
	// in favor of cost_per_response_nanos
	Nanos int64 `json:"nanos,omitempty,string"`

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

// SurveyQuestion: Message defining the question specifications.
type SurveyQuestion struct {
	// AnswerOrder: The randomization option for multiple choice and
	// multi-select questions. If not specified, this option defaults to
	// randomize.
	AnswerOrder string `json:"answerOrder,omitempty"`

	// Answers: Required list of answer options for a question.
	Answers []string `json:"answers,omitempty"`

	// HasOther: Option to allow open-ended text box for Single Answer and
	// Multiple Answer question types. This can be used with SINGLE_ANSWER,
	// SINGLE_ANSWER_WITH_IMAGE, MULTIPLE_ANSWERS, and
	// MULTIPLE_ANSWERS_WITH_IMAGE question types.
	HasOther bool `json:"hasOther,omitempty"`

	// HighValueLabel: For rating questions, the text for the higher end of
	// the scale, such as 'Best'. For numeric questions, a string
	// representing a floating-point that is the maximum allowed number for
	// a response.
	HighValueLabel string `json:"highValueLabel,omitempty"`

	Images []*SurveyQuestionImage `json:"images,omitempty"`

	// LastAnswerPositionPinned: Currently only support pinning an answer
	// option to the last position.
	LastAnswerPositionPinned bool `json:"lastAnswerPositionPinned,omitempty"`

	// LowValueLabel: For rating questions, the text for the lower end of
	// the scale, such as 'Worst'. For numeric questions, a string
	// representing a floating-point that is the minimum allowed number for
	// a response.
	LowValueLabel string `json:"lowValueLabel,omitempty"`

	// MustPickSuggestion: Option to force the user to pick one of the open
	// text suggestions. This requires that suggestions are provided for
	// this question.
	MustPickSuggestion bool `json:"mustPickSuggestion,omitempty"`

	// NumStars: Number of stars to use for ratings questions.
	NumStars string `json:"numStars,omitempty"`

	// OpenTextPlaceholder: Placeholder text for an open text question.
	OpenTextPlaceholder string `json:"openTextPlaceholder,omitempty"`

	// OpenTextSuggestions: A list of suggested answers for open text
	// question auto-complete. This is only valid if single_line_response is
	// true.
	OpenTextSuggestions []string `json:"openTextSuggestions,omitempty"`

	// Question: Required question text shown to the respondent.
	Question string `json:"question,omitempty"`

	// SentimentText: Used by the Rating Scale with Text question type. This
	// text goes along with the question field that is presented to the
	// respondent, and is the actual text that the respondent is asked to
	// rate.
	SentimentText string `json:"sentimentText,omitempty"`

	// SingleLineResponse: Option to allow multiple line open text responses
	// instead of a single line response. Note that we don't show
	// auto-complete suggestions with multiple line responses.
	SingleLineResponse bool `json:"singleLineResponse,omitempty"`

	// ThresholdAnswers: The threshold/screener answer options, which will
	// screen a user into the rest of the survey. These will be a subset of
	// the answer option strings.
	ThresholdAnswers []string `json:"thresholdAnswers,omitempty"`

	// Type: Required field defining the question type. For details about
	// configuring different type of questions, consult the question
	// configuration guide.
	Type string `json:"type,omitempty"`

	// UnitOfMeasurementLabel: Optional unit of measurement for display (for
	// example: hours, people, miles).
	UnitOfMeasurementLabel string `json:"unitOfMeasurementLabel,omitempty"`

	// VideoId: The YouTube video ID to be show in video questions.
	VideoId string `json:"videoId,omitempty"`

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

// SurveyQuestionImage: Container object for image data and alt_text.
type SurveyQuestionImage struct {
	// AltText: The alt text property used in image tags is required for all
	// images.
	AltText string `json:"altText,omitempty"`

	// Data: Inline jpeg, gif, tiff, bmp, or png image raw bytes for an
	// image question types.
	Data string `json:"data,omitempty"`

	// Url: The read-only URL for the hosted images.
	Url string `json:"url,omitempty"`

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

// SurveyRejection: Message representing why the survey was rejected
// from review, if it was.
type SurveyRejection struct {
	// Explanation: A human-readable explanation of what was wrong with the
	// survey.
	Explanation string `json:"explanation,omitempty"`

	// Type: Which category of rejection this was. See the  Google Surveys
	// Help Center for additional details on each category.
	Type string `json:"type,omitempty"`

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

// SurveyResults: Reference to the current results for a given survey.
type SurveyResults struct {
	// Status: Human readable string describing the status of the request.
	Status string `json:"status,omitempty"`

	// SurveyUrlId: External survey ID as viewable by survey owners in the
	// editor view.
	SurveyUrlId string `json:"surveyUrlId,omitempty"`

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

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

type SurveysDeleteResponse struct {
	// RequestId: Unique request ID used for logging and debugging. Please
	// include in any error reporting or troubleshooting requests.
	RequestId string `json:"requestId,omitempty"`

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

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

type SurveysListResponse struct {
	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	// RequestId: Unique request ID used for logging and debugging. Please
	// include in any error reporting or troubleshooting requests.
	RequestId string `json:"requestId,omitempty"`

	// Resources: An individual survey resource.
	Resources []*Survey `json:"resources,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

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

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

type SurveysStartRequest struct {
	// MaxCostPerResponseNanos: *Deprecated* Threshold to start a survey
	// automatically if the quoted prices is less than or equal to this
	// value. See Survey.Cost for more details. This will no longer be
	// available after June 2018.
	MaxCostPerResponseNanos int64 `json:"maxCostPerResponseNanos,omitempty,string"`

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

type SurveysStartResponse struct {
	// RequestId: Unique request ID used for logging and debugging. Please
	// include in any error reporting or troubleshooting requests.
	RequestId string `json:"requestId,omitempty"`

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

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

type SurveysStopResponse struct {
	// RequestId: Unique request ID used for logging and debugging. Please
	// include in any error reporting or troubleshooting requests.
	RequestId string `json:"requestId,omitempty"`

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

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

type TokenPagination struct {
	NextPageToken string `json:"nextPageToken,omitempty"`

	PreviousPageToken string `json:"previousPageToken,omitempty"`

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

// method id "surveys.results.get":

type ResultsGetCall struct {
	s                 *Service
	surveyUrlId       string
	resultsgetrequest *ResultsGetRequest
	urlParams_        gensupport.URLParams
	ifNoneMatch_      string
	ctx_              context.Context
	header_           http.Header
}

// Get: Retrieves any survey results that have been produced so far.
// Results are formatted as an Excel file. You must add "?alt=media" to
// the URL as an argument to get results.
func (r *ResultsService) Get(surveyUrlId string, resultsgetrequest *ResultsGetRequest) *ResultsGetCall {
	c := &ResultsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.surveyUrlId = surveyUrlId
	c.resultsgetrequest = resultsgetrequest
	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 *ResultsGetCall) Fields(s ...googleapi.Field) *ResultsGetCall {
	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 *ResultsGetCall) IfNoneMatch(entityTag string) *ResultsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do and Download
// methods. Any pending HTTP request will be aborted if the provided
// context is canceled.
func (c *ResultsGetCall) Context(ctx context.Context) *ResultsGetCall {
	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 *ResultsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ResultsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "surveys/{surveyUrlId}/results")
	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{
		"surveyUrlId": c.surveyUrlId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Download fetches the API endpoint's "media" value, instead of the normal
// API response value. If the returned error is nil, the Response is guaranteed to
// have a 2xx status code. Callers must close the Response.Body as usual.
func (c *ResultsGetCall) Download(opts ...googleapi.CallOption) (*http.Response, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("media")
	if err != nil {
		return nil, err
	}
	if err := googleapi.CheckMediaResponse(res); err != nil {
		res.Body.Close()
		return nil, err
	}
	return res, nil
}

// Do executes the "surveys.results.get" call.
// Exactly one of *SurveyResults or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *SurveyResults.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 *ResultsGetCall) Do(opts ...googleapi.CallOption) (*SurveyResults, 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 := &SurveyResults{
		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": "Retrieves any survey results that have been produced so far. Results are formatted as an Excel file. You must add \"?alt=media\" to the URL as an argument to get results.",
	//   "httpMethod": "GET",
	//   "id": "surveys.results.get",
	//   "parameterOrder": [
	//     "surveyUrlId"
	//   ],
	//   "parameters": {
	//     "surveyUrlId": {
	//       "description": "External URL ID for the survey.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "surveys/{surveyUrlId}/results",
	//   "request": {
	//     "$ref": "ResultsGetRequest"
	//   },
	//   "response": {
	//     "$ref": "SurveyResults"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/surveys",
	//     "https://www.googleapis.com/auth/surveys.readonly",
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ],
	//   "supportsMediaDownload": true
	// }

}

// method id "surveys.surveys.delete":

type SurveysDeleteCall struct {
	s           *Service
	surveyUrlId string
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Delete: Removes a survey from view in all user GET requests.
func (r *SurveysService) Delete(surveyUrlId string) *SurveysDeleteCall {
	c := &SurveysDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.surveyUrlId = surveyUrlId
	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 *SurveysDeleteCall) Fields(s ...googleapi.Field) *SurveysDeleteCall {
	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 *SurveysDeleteCall) Context(ctx context.Context) *SurveysDeleteCall {
	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 *SurveysDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SurveysDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "surveys/{surveyUrlId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"surveyUrlId": c.surveyUrlId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "surveys.surveys.delete" call.
// Exactly one of *SurveysDeleteResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SurveysDeleteResponse.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 *SurveysDeleteCall) Do(opts ...googleapi.CallOption) (*SurveysDeleteResponse, 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 := &SurveysDeleteResponse{
		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": "Removes a survey from view in all user GET requests.",
	//   "httpMethod": "DELETE",
	//   "id": "surveys.surveys.delete",
	//   "parameterOrder": [
	//     "surveyUrlId"
	//   ],
	//   "parameters": {
	//     "surveyUrlId": {
	//       "description": "External URL ID for the survey.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "surveys/{surveyUrlId}",
	//   "response": {
	//     "$ref": "SurveysDeleteResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/surveys",
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}

// method id "surveys.surveys.get":

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

// Get: Retrieves information about the specified survey.
func (r *SurveysService) Get(surveyUrlId string) *SurveysGetCall {
	c := &SurveysGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.surveyUrlId = surveyUrlId
	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 *SurveysGetCall) Fields(s ...googleapi.Field) *SurveysGetCall {
	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 *SurveysGetCall) IfNoneMatch(entityTag string) *SurveysGetCall {
	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 *SurveysGetCall) Context(ctx context.Context) *SurveysGetCall {
	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 *SurveysGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SurveysGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "surveys/{surveyUrlId}")
	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{
		"surveyUrlId": c.surveyUrlId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "surveys.surveys.get" call.
// Exactly one of *Survey or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Survey.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 *SurveysGetCall) Do(opts ...googleapi.CallOption) (*Survey, 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 := &Survey{
		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": "Retrieves information about the specified survey.",
	//   "httpMethod": "GET",
	//   "id": "surveys.surveys.get",
	//   "parameterOrder": [
	//     "surveyUrlId"
	//   ],
	//   "parameters": {
	//     "surveyUrlId": {
	//       "description": "External URL ID for the survey.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "surveys/{surveyUrlId}",
	//   "response": {
	//     "$ref": "Survey"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/surveys",
	//     "https://www.googleapis.com/auth/surveys.readonly",
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}

// method id "surveys.surveys.insert":

type SurveysInsertCall struct {
	s          *Service
	survey     *Survey
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a survey.
func (r *SurveysService) Insert(survey *Survey) *SurveysInsertCall {
	c := &SurveysInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.survey = survey
	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 *SurveysInsertCall) Fields(s ...googleapi.Field) *SurveysInsertCall {
	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 *SurveysInsertCall) Context(ctx context.Context) *SurveysInsertCall {
	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 *SurveysInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SurveysInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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.survey)
	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, "surveys")
	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 "surveys.surveys.insert" call.
// Exactly one of *Survey or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Survey.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 *SurveysInsertCall) Do(opts ...googleapi.CallOption) (*Survey, 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 := &Survey{
		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 survey.",
	//   "httpMethod": "POST",
	//   "id": "surveys.surveys.insert",
	//   "path": "surveys",
	//   "request": {
	//     "$ref": "Survey"
	//   },
	//   "response": {
	//     "$ref": "Survey"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/surveys",
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}

// method id "surveys.surveys.list":

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

// List: Lists the surveys owned by the authenticated user.
func (r *SurveysService) List() *SurveysListCall {
	c := &SurveysListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// MaxResults sets the optional parameter "maxResults":
func (c *SurveysListCall) MaxResults(maxResults int64) *SurveysListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// StartIndex sets the optional parameter "startIndex":
func (c *SurveysListCall) StartIndex(startIndex int64) *SurveysListCall {
	c.urlParams_.Set("startIndex", fmt.Sprint(startIndex))
	return c
}

// Token sets the optional parameter "token":
func (c *SurveysListCall) Token(token string) *SurveysListCall {
	c.urlParams_.Set("token", token)
	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 *SurveysListCall) Fields(s ...googleapi.Field) *SurveysListCall {
	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 *SurveysListCall) IfNoneMatch(entityTag string) *SurveysListCall {
	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 *SurveysListCall) Context(ctx context.Context) *SurveysListCall {
	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 *SurveysListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SurveysListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "surveys")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "surveys.surveys.list" call.
// Exactly one of *SurveysListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SurveysListResponse.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 *SurveysListCall) Do(opts ...googleapi.CallOption) (*SurveysListResponse, 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 := &SurveysListResponse{
		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": "Lists the surveys owned by the authenticated user.",
	//   "httpMethod": "GET",
	//   "id": "surveys.surveys.list",
	//   "parameters": {
	//     "maxResults": {
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "startIndex": {
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "token": {
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "surveys",
	//   "response": {
	//     "$ref": "SurveysListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/surveys",
	//     "https://www.googleapis.com/auth/surveys.readonly",
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}

// method id "surveys.surveys.start":

type SurveysStartCall struct {
	s                   *Service
	resourceId          string
	surveysstartrequest *SurveysStartRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// Start: Begins running a survey.
func (r *SurveysService) Start(resourceId string, surveysstartrequest *SurveysStartRequest) *SurveysStartCall {
	c := &SurveysStartCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceId = resourceId
	c.surveysstartrequest = surveysstartrequest
	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 *SurveysStartCall) Fields(s ...googleapi.Field) *SurveysStartCall {
	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 *SurveysStartCall) Context(ctx context.Context) *SurveysStartCall {
	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 *SurveysStartCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SurveysStartCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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.surveysstartrequest)
	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, "surveys/{resourceId}/start")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resourceId": c.resourceId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "surveys.surveys.start" call.
// Exactly one of *SurveysStartResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SurveysStartResponse.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 *SurveysStartCall) Do(opts ...googleapi.CallOption) (*SurveysStartResponse, 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 := &SurveysStartResponse{
		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": "Begins running a survey.",
	//   "httpMethod": "POST",
	//   "id": "surveys.surveys.start",
	//   "parameterOrder": [
	//     "resourceId"
	//   ],
	//   "parameters": {
	//     "resourceId": {
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "surveys/{resourceId}/start",
	//   "request": {
	//     "$ref": "SurveysStartRequest"
	//   },
	//   "response": {
	//     "$ref": "SurveysStartResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/surveys",
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}

// method id "surveys.surveys.stop":

type SurveysStopCall struct {
	s          *Service
	resourceId string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Stop: Stops a running survey.
func (r *SurveysService) Stop(resourceId string) *SurveysStopCall {
	c := &SurveysStopCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceId = resourceId
	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 *SurveysStopCall) Fields(s ...googleapi.Field) *SurveysStopCall {
	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 *SurveysStopCall) Context(ctx context.Context) *SurveysStopCall {
	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 *SurveysStopCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SurveysStopCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "surveys/{resourceId}/stop")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resourceId": c.resourceId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "surveys.surveys.stop" call.
// Exactly one of *SurveysStopResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SurveysStopResponse.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 *SurveysStopCall) Do(opts ...googleapi.CallOption) (*SurveysStopResponse, 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 := &SurveysStopResponse{
		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": "Stops a running survey.",
	//   "httpMethod": "POST",
	//   "id": "surveys.surveys.stop",
	//   "parameterOrder": [
	//     "resourceId"
	//   ],
	//   "parameters": {
	//     "resourceId": {
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "surveys/{resourceId}/stop",
	//   "response": {
	//     "$ref": "SurveysStopResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/surveys",
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}

// method id "surveys.surveys.update":

type SurveysUpdateCall struct {
	s           *Service
	surveyUrlId string
	survey      *Survey
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Update: Updates a survey. Currently the only property that can be
// updated is the owners property.
func (r *SurveysService) Update(surveyUrlId string, survey *Survey) *SurveysUpdateCall {
	c := &SurveysUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.surveyUrlId = surveyUrlId
	c.survey = survey
	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 *SurveysUpdateCall) Fields(s ...googleapi.Field) *SurveysUpdateCall {
	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 *SurveysUpdateCall) Context(ctx context.Context) *SurveysUpdateCall {
	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 *SurveysUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SurveysUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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.survey)
	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, "surveys/{surveyUrlId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"surveyUrlId": c.surveyUrlId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "surveys.surveys.update" call.
// Exactly one of *Survey or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Survey.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 *SurveysUpdateCall) Do(opts ...googleapi.CallOption) (*Survey, 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 := &Survey{
		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": "Updates a survey. Currently the only property that can be updated is the owners property.",
	//   "httpMethod": "PUT",
	//   "id": "surveys.surveys.update",
	//   "parameterOrder": [
	//     "surveyUrlId"
	//   ],
	//   "parameters": {
	//     "surveyUrlId": {
	//       "description": "External URL ID for the survey.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "surveys/{surveyUrlId}",
	//   "request": {
	//     "$ref": "Survey"
	//   },
	//   "response": {
	//     "$ref": "Survey"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/surveys",
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}
