// 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 factchecktools provides access to the Fact Check Tools API.
//
// For product documentation, see: https://developers.google.com/fact-check/tools/api/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/factchecktools/v1alpha1"
//   ...
//   ctx := context.Background()
//   factchecktoolsService, err := factchecktools.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:
//
//   factchecktoolsService, err := factchecktools.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, ...)
//   factchecktoolsService, err := factchecktools.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package factchecktools // import "google.golang.org/api/factchecktools/v1alpha1"

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 = "factchecktools:v1alpha1"
const apiName = "factchecktools"
const apiVersion = "v1alpha1"
const basePath = "https://factchecktools.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// 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/userinfo.email",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Claims = NewClaimsService(s)
	s.Pages = NewPagesService(s)
	return s, nil
}

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

	Claims *ClaimsService

	Pages *PagesService
}

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

func NewClaimsService(s *Service) *ClaimsService {
	rs := &ClaimsService{s: s}
	return rs
}

type ClaimsService struct {
	s *Service
}

func NewPagesService(s *Service) *PagesService {
	rs := &PagesService{s: s}
	return rs
}

type PagesService struct {
	s *Service
}

// GoogleFactcheckingFactchecktoolsV1alpha1Claim: Information about the
// claim.
type GoogleFactcheckingFactchecktoolsV1alpha1Claim struct {
	// ClaimDate: The date that the claim was made.
	ClaimDate string `json:"claimDate,omitempty"`

	// ClaimReview: One or more reviews of this claim (namely, a
	// fact-checking article).
	ClaimReview []*GoogleFactcheckingFactchecktoolsV1alpha1ClaimReview `json:"claimReview,omitempty"`

	// Claimant: A person or organization stating the claim. For instance,
	// "John Doe".
	Claimant string `json:"claimant,omitempty"`

	// Text: The claim text. For instance, "Crime has doubled in the last 2
	// years."
	Text string `json:"text,omitempty"`

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

// GoogleFactcheckingFactchecktoolsV1alpha1ClaimAuthor: Information
// about the claim author.
type GoogleFactcheckingFactchecktoolsV1alpha1ClaimAuthor struct {
	// ImageUrl: Corresponds to `ClaimReview.itemReviewed.author.image`.
	ImageUrl string `json:"imageUrl,omitempty"`

	// JobTitle: Corresponds to `ClaimReview.itemReviewed.author.jobTitle`.
	JobTitle string `json:"jobTitle,omitempty"`

	// Name: A person or organization stating the claim. For instance, "John
	// Doe".<br>
	// Corresponds to `ClaimReview.itemReviewed.author.name`.
	Name string `json:"name,omitempty"`

	// SameAs: Corresponds to `ClaimReview.itemReviewed.author.sameAs`.
	SameAs string `json:"sameAs,omitempty"`

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

// GoogleFactcheckingFactchecktoolsV1alpha1ClaimRating: Information
// about the claim rating.
type GoogleFactcheckingFactchecktoolsV1alpha1ClaimRating struct {
	// BestRating: For numeric ratings, the best value possible in the scale
	// from worst to
	// best.<br>
	// Corresponds to `ClaimReview.reviewRating.bestRating`.
	BestRating int64 `json:"bestRating,omitempty"`

	// ImageUrl: Corresponds to `ClaimReview.reviewRating.image`.
	ImageUrl string `json:"imageUrl,omitempty"`

	// RatingExplanation: Corresponds to
	// `ClaimReview.reviewRating.ratingExplanation`.
	RatingExplanation string `json:"ratingExplanation,omitempty"`

	// RatingValue: A numeric rating of this claim, in the range worstRating
	// — bestRating
	// inclusive.<br>
	// Corresponds to `ClaimReview.reviewRating.ratingValue`.
	RatingValue int64 `json:"ratingValue,omitempty"`

	// TextualRating: The truthfulness rating as a human-readible short word
	// or phrase.<br>
	// Corresponds to `ClaimReview.reviewRating.alternateName`.
	TextualRating string `json:"textualRating,omitempty"`

	// WorstRating: For numeric ratings, the worst value possible in the
	// scale from worst to
	// best.<br>
	// Corresponds to `ClaimReview.reviewRating.worstRating`.
	WorstRating int64 `json:"worstRating,omitempty"`

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

// GoogleFactcheckingFactchecktoolsV1alpha1ClaimReview: Information
// about a claim review.
type GoogleFactcheckingFactchecktoolsV1alpha1ClaimReview struct {
	// LanguageCode: The language this review was written in. For instance,
	// "en" or "de".
	LanguageCode string `json:"languageCode,omitempty"`

	// Publisher: The publisher of this claim review.
	Publisher *GoogleFactcheckingFactchecktoolsV1alpha1Publisher `json:"publisher,omitempty"`

	// ReviewDate: The date the claim was reviewed.
	ReviewDate string `json:"reviewDate,omitempty"`

	// TextualRating: Textual rating. For instance, "Mostly false".
	TextualRating string `json:"textualRating,omitempty"`

	// Title: The title of this claim review, if it can be determined.
	Title string `json:"title,omitempty"`

	// Url: The URL of this claim review.
	Url string `json:"url,omitempty"`

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

// GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewAuthor:
// Information about the claim review author.
type GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewAuthor struct {
	// ImageUrl: Corresponds to `ClaimReview.author.image`.
	ImageUrl string `json:"imageUrl,omitempty"`

	// Name: Name of the organization that is publishing the fact
	// check.<br>
	// Corresponds to `ClaimReview.author.name`.
	Name string `json:"name,omitempty"`

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

// GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkup: Fields for
// an individual `ClaimReview` element.
// Except for sub-messages that group fields together, each of these
// fields
// correspond those in https://schema.org/ClaimReview. We list the
// precise
// mapping for each field.
type GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkup struct {
	// ClaimAppearances: A list of links to works in which this claim
	// appears, aside from the one
	// specified in `claim_first_appearance`.<br>
	// Corresponds to
	// `ClaimReview.itemReviewed[@type=Claim].appearance.url`.
	ClaimAppearances []string `json:"claimAppearances,omitempty"`

	// ClaimAuthor: Info about the author of this claim.
	ClaimAuthor *GoogleFactcheckingFactchecktoolsV1alpha1ClaimAuthor `json:"claimAuthor,omitempty"`

	// ClaimDate: The date when the claim was made or entered public
	// discourse.<br>
	// Corresponds to `ClaimReview.itemReviewed.datePublished`.
	ClaimDate string `json:"claimDate,omitempty"`

	// ClaimFirstAppearance: A link to a work in which this claim first
	// appears.<br>
	// Corresponds to
	// `ClaimReview.itemReviewed[@type=Claim].firstAppearance.url`.
	ClaimFirstAppearance string `json:"claimFirstAppearance,omitempty"`

	// ClaimLocation: The location where this claim was
	// made.<br>
	// Corresponds to `ClaimReview.itemReviewed.name`.
	ClaimLocation string `json:"claimLocation,omitempty"`

	// ClaimReviewed: A short summary of the claim being
	// evaluated.<br>
	// Corresponds to `ClaimReview.claimReviewed`.
	ClaimReviewed string `json:"claimReviewed,omitempty"`

	// Rating: Info about the rating of this claim review.
	Rating *GoogleFactcheckingFactchecktoolsV1alpha1ClaimRating `json:"rating,omitempty"`

	// Url: This field is optional, and will default to the page URL. We
	// provide this
	// field to allow you the override the default value, but the only
	// permitted
	// override is the page URL plus an optional anchor link ("page
	// jump").<br>
	// Corresponds to `ClaimReview.url`
	Url string `json:"url,omitempty"`

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

// GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage: Holds
// one or more instances of `ClaimReview` markup for a webpage.
type GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage struct {
	// ClaimReviewAuthor: Info about the author of this claim
	// review.
	// Similar to the above, semantically these are page-level fields, and
	// each
	// `ClaimReview` on this page will contain the same values.
	ClaimReviewAuthor *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewAuthor `json:"claimReviewAuthor,omitempty"`

	// ClaimReviewMarkups: A list of individual claim reviews for this
	// page.
	// Each item in the list corresponds to one `ClaimReview` element.
	ClaimReviewMarkups []*GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkup `json:"claimReviewMarkups,omitempty"`

	// Name: The name of this `ClaimReview` markup page resource, in the
	// form of
	// `pages/{page_id}`. Except for update requests, this field is
	// output-only
	// and should not be set by the user.
	Name string `json:"name,omitempty"`

	// PageUrl: The URL of the page associated with this `ClaimReview`
	// markup.
	// While every individual `ClaimReview` has its own URL field,
	// semantically
	// this is a page-level field, and each `ClaimReview` on this page will
	// use
	// this value unless individually overridden.<br>
	// Corresponds to `ClaimReview.url`
	PageUrl string `json:"pageUrl,omitempty"`

	// PublishDate: The date when the fact check was published.
	// Similar to the URL, semantically this is a page-level field, and
	// each
	// `ClaimReview` on this page will contain the same
	// value.<br>
	// Corresponds to `ClaimReview.datePublished`
	PublishDate string `json:"publishDate,omitempty"`

	// VersionId: The version ID for this markup. Except for update
	// requests, this field is
	// output-only and should not be set by the user.
	VersionId string `json:"versionId,omitempty"`

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

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

// GoogleFactcheckingFactchecktoolsV1alpha1FactCheckedClaimSearchResponse
// : Response from searching fact-checked claims.
type GoogleFactcheckingFactchecktoolsV1alpha1FactCheckedClaimSearchResponse struct {
	// Claims: The list of claims and all of their associated information.
	Claims []*GoogleFactcheckingFactchecktoolsV1alpha1Claim `json:"claims,omitempty"`

	// NextPageToken: The next pagination token in the Search response. It
	// should be used as the
	// `page_token` for the following request. An empty value means no
	// more
	// results.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

// GoogleFactcheckingFactchecktoolsV1alpha1ListClaimReviewMarkupPagesResp
// onse: Response from listing `ClaimReview` markup.
type GoogleFactcheckingFactchecktoolsV1alpha1ListClaimReviewMarkupPagesResponse struct {
	// ClaimReviewMarkupPages: The result list of pages of `ClaimReview`
	// markup.
	ClaimReviewMarkupPages []*GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage `json:"claimReviewMarkupPages,omitempty"`

	// NextPageToken: The next pagination token in the Search response. It
	// should be used as the
	// `page_token` for the following request. An empty value means no
	// more
	// results.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

// GoogleFactcheckingFactchecktoolsV1alpha1Publisher: Information about
// the publisher.
type GoogleFactcheckingFactchecktoolsV1alpha1Publisher struct {
	// Name: The name of this publisher. For instance, "Awesome Fact
	// Checks".
	Name string `json:"name,omitempty"`

	// Site: Host-level site name, without the protocol or "www" prefix. For
	// instance,
	// "awesomefactchecks.com". This value of this field is based purely on
	// the
	// claim review URL.
	Site string `json:"site,omitempty"`

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

// GoogleProtobufEmpty: A generic empty message that you can re-use to
// avoid defining duplicated
// empty messages in your APIs. A typical example is to use it as the
// request
// or the response type of an API method. For instance:
//
//     service Foo {
//       rpc Bar(google.protobuf.Empty) returns
// (google.protobuf.Empty);
//     }
//
// The JSON representation for `Empty` is empty JSON object `{}`.
type GoogleProtobufEmpty struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// method id "factchecktools.claims.search":

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

// Search: Search through fact-checked claims.
func (r *ClaimsService) Search() *ClaimsSearchCall {
	c := &ClaimsSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// LanguageCode sets the optional parameter "languageCode": The BCP-47
// language code, such as "en-US" or "sr-Latn". Can be used to
// restrict results by language, though we do not currently consider
// the
// region.
func (c *ClaimsSearchCall) LanguageCode(languageCode string) *ClaimsSearchCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// MaxAgeDays sets the optional parameter "maxAgeDays": The maximum age
// of the returned search results, in days.
// Age is determined by either claim date or review date, whichever is
// newer.
func (c *ClaimsSearchCall) MaxAgeDays(maxAgeDays int64) *ClaimsSearchCall {
	c.urlParams_.Set("maxAgeDays", fmt.Sprint(maxAgeDays))
	return c
}

// Offset sets the optional parameter "offset": An integer that
// specifies the current offset (that is, starting result
// location) in search results. This field is only considered if
// `page_token`
// is unset. For example, 0 means to return results starting from the
// first
// matching result, and 10 means to return from the 11th result.
func (c *ClaimsSearchCall) Offset(offset int64) *ClaimsSearchCall {
	c.urlParams_.Set("offset", fmt.Sprint(offset))
	return c
}

// PageSize sets the optional parameter "pageSize": The pagination size.
// We will return up to that many results. Defaults to
// 10 if not set.
func (c *ClaimsSearchCall) PageSize(pageSize int64) *ClaimsSearchCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The pagination
// token. You may provide the `next_page_token` returned from a
// previous List request, if any, in order to get the next page. All
// other
// fields must have the same values as in the previous request.
func (c *ClaimsSearchCall) PageToken(pageToken string) *ClaimsSearchCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Query sets the optional parameter "query": Textual query string.
// Required unless `review_publisher_site_filter` is
// specified.
func (c *ClaimsSearchCall) Query(query string) *ClaimsSearchCall {
	c.urlParams_.Set("query", query)
	return c
}

// ReviewPublisherSiteFilter sets the optional parameter
// "reviewPublisherSiteFilter": The review publisher site to filter
// results by, e.g. nytimes.com.
func (c *ClaimsSearchCall) ReviewPublisherSiteFilter(reviewPublisherSiteFilter string) *ClaimsSearchCall {
	c.urlParams_.Set("reviewPublisherSiteFilter", reviewPublisherSiteFilter)
	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 *ClaimsSearchCall) Fields(s ...googleapi.Field) *ClaimsSearchCall {
	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 *ClaimsSearchCall) IfNoneMatch(entityTag string) *ClaimsSearchCall {
	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 *ClaimsSearchCall) Context(ctx context.Context) *ClaimsSearchCall {
	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 *ClaimsSearchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ClaimsSearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200220")
	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, "v1alpha1/claims:search")
	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 "factchecktools.claims.search" call.
// Exactly one of
// *GoogleFactcheckingFactchecktoolsV1alpha1FactCheckedClaimSearchRespons
// e or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleFactcheckingFactchecktoolsV1alpha1FactCheckedClaimSearchRespons
// e.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 *ClaimsSearchCall) Do(opts ...googleapi.CallOption) (*GoogleFactcheckingFactchecktoolsV1alpha1FactCheckedClaimSearchResponse, 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 := &GoogleFactcheckingFactchecktoolsV1alpha1FactCheckedClaimSearchResponse{
		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": "Search through fact-checked claims.",
	//   "flatPath": "v1alpha1/claims:search",
	//   "httpMethod": "GET",
	//   "id": "factchecktools.claims.search",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "languageCode": {
	//       "description": "The BCP-47 language code, such as \"en-US\" or \"sr-Latn\". Can be used to\nrestrict results by language, though we do not currently consider the\nregion.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxAgeDays": {
	//       "description": "The maximum age of the returned search results, in days.\nAge is determined by either claim date or review date, whichever is newer.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "offset": {
	//       "description": "An integer that specifies the current offset (that is, starting result\nlocation) in search results. This field is only considered if `page_token`\nis unset. For example, 0 means to return results starting from the first\nmatching result, and 10 means to return from the 11th result.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageSize": {
	//       "description": "The pagination size. We will return up to that many results. Defaults to\n10 if not set.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The pagination token. You may provide the `next_page_token` returned from a\nprevious List request, if any, in order to get the next page. All other\nfields must have the same values as in the previous request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "Textual query string. Required unless `review_publisher_site_filter` is\nspecified.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "reviewPublisherSiteFilter": {
	//       "description": "The review publisher site to filter results by, e.g. nytimes.com.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/claims:search",
	//   "response": {
	//     "$ref": "GoogleFactcheckingFactchecktoolsV1alpha1FactCheckedClaimSearchResponse"
	//   }
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ClaimsSearchCall) Pages(ctx context.Context, f func(*GoogleFactcheckingFactchecktoolsV1alpha1FactCheckedClaimSearchResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "factchecktools.pages.create":

type PagesCreateCall struct {
	s                                                             *Service
	googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage
	urlParams_                                                    gensupport.URLParams
	ctx_                                                          context.Context
	header_                                                       http.Header
}

// Create: Create `ClaimReview` markup on a page.
func (r *PagesService) Create(googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage) *PagesCreateCall {
	c := &PagesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage = googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage
	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 *PagesCreateCall) Fields(s ...googleapi.Field) *PagesCreateCall {
	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 *PagesCreateCall) Context(ctx context.Context) *PagesCreateCall {
	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 *PagesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PagesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200220")
	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.googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage)
	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, "v1alpha1/pages")
	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 "factchecktools.pages.create" call.
// Exactly one of
// *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage.ServerR
// esponse.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 *PagesCreateCall) Do(opts ...googleapi.CallOption) (*GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage, 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 := &GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage{
		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": "Create `ClaimReview` markup on a page.",
	//   "flatPath": "v1alpha1/pages",
	//   "httpMethod": "POST",
	//   "id": "factchecktools.pages.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1alpha1/pages",
	//   "request": {
	//     "$ref": "GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage"
	//   },
	//   "response": {
	//     "$ref": "GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}

// method id "factchecktools.pages.delete":

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

// Delete: Delete all `ClaimReview` markup on a page.
func (r *PagesService) Delete(name string) *PagesDeleteCall {
	c := &PagesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *PagesDeleteCall) Fields(s ...googleapi.Field) *PagesDeleteCall {
	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 *PagesDeleteCall) Context(ctx context.Context) *PagesDeleteCall {
	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 *PagesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PagesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200220")
	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, "v1alpha1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "factchecktools.pages.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *PagesDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Delete all `ClaimReview` markup on a page.",
	//   "flatPath": "v1alpha1/pages/{pagesId}",
	//   "httpMethod": "DELETE",
	//   "id": "factchecktools.pages.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the resource to delete, in the form of `pages/{page_id}`.",
	//       "location": "path",
	//       "pattern": "^pages/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}

// method id "factchecktools.pages.get":

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

// Get: Get all `ClaimReview` markup on a page.
func (r *PagesService) Get(name string) *PagesGetCall {
	c := &PagesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *PagesGetCall) Fields(s ...googleapi.Field) *PagesGetCall {
	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 *PagesGetCall) IfNoneMatch(entityTag string) *PagesGetCall {
	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 *PagesGetCall) Context(ctx context.Context) *PagesGetCall {
	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 *PagesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PagesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200220")
	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, "v1alpha1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "factchecktools.pages.get" call.
// Exactly one of
// *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage.ServerR
// esponse.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 *PagesGetCall) Do(opts ...googleapi.CallOption) (*GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage, 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 := &GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage{
		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 all `ClaimReview` markup on a page.",
	//   "flatPath": "v1alpha1/pages/{pagesId}",
	//   "httpMethod": "GET",
	//   "id": "factchecktools.pages.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the resource to get, in the form of `pages/{page_id}`.",
	//       "location": "path",
	//       "pattern": "^pages/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}

// method id "factchecktools.pages.list":

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

// List: List the `ClaimReview` markup pages for a specific URL or for
// an
// organization.
func (r *PagesService) List() *PagesListCall {
	c := &PagesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// Offset sets the optional parameter "offset": An integer that
// specifies the current offset (that is, starting result
// location) in search results. This field is only considered if
// `page_token`
// is unset, and if the request is not for a specific URL. For example,
// 0
// means to return results starting from the first matching result, and
// 10
// means to return from the 11th result.
func (c *PagesListCall) Offset(offset int64) *PagesListCall {
	c.urlParams_.Set("offset", fmt.Sprint(offset))
	return c
}

// Organization sets the optional parameter "organization": The
// organization for which we want to fetch markups for. For
// instance,
// "site.com". Cannot be specified along with an URL.
func (c *PagesListCall) Organization(organization string) *PagesListCall {
	c.urlParams_.Set("organization", organization)
	return c
}

// PageSize sets the optional parameter "pageSize": The pagination size.
// We will return up to that many results. Defaults to
// 10 if not set. Has no effect if a URL is requested.
func (c *PagesListCall) PageSize(pageSize int64) *PagesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The pagination
// token. You may provide the `next_page_token` returned from a
// previous List request, if any, in order to get the next page. All
// other
// fields must have the same values as in the previous request.
func (c *PagesListCall) PageToken(pageToken string) *PagesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Url sets the optional parameter "url": The URL from which to get
// `ClaimReview` markup. There will be at most one
// result. If markup is associated with a more canonical version of the
// URL
// provided, we will return that URL instead. Cannot be specified along
// with
// an organization.
func (c *PagesListCall) Url(url string) *PagesListCall {
	c.urlParams_.Set("url", url)
	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 *PagesListCall) Fields(s ...googleapi.Field) *PagesListCall {
	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 *PagesListCall) IfNoneMatch(entityTag string) *PagesListCall {
	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 *PagesListCall) Context(ctx context.Context) *PagesListCall {
	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 *PagesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PagesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200220")
	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, "v1alpha1/pages")
	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 "factchecktools.pages.list" call.
// Exactly one of
// *GoogleFactcheckingFactchecktoolsV1alpha1ListClaimReviewMarkupPagesRes
// ponse or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleFactcheckingFactchecktoolsV1alpha1ListClaimReviewMarkupPagesRes
// ponse.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 *PagesListCall) Do(opts ...googleapi.CallOption) (*GoogleFactcheckingFactchecktoolsV1alpha1ListClaimReviewMarkupPagesResponse, 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 := &GoogleFactcheckingFactchecktoolsV1alpha1ListClaimReviewMarkupPagesResponse{
		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": "List the `ClaimReview` markup pages for a specific URL or for an\norganization.",
	//   "flatPath": "v1alpha1/pages",
	//   "httpMethod": "GET",
	//   "id": "factchecktools.pages.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "offset": {
	//       "description": "An integer that specifies the current offset (that is, starting result\nlocation) in search results. This field is only considered if `page_token`\nis unset, and if the request is not for a specific URL. For example, 0\nmeans to return results starting from the first matching result, and 10\nmeans to return from the 11th result.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "organization": {
	//       "description": "The organization for which we want to fetch markups for. For instance,\n\"site.com\". Cannot be specified along with an URL.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The pagination size. We will return up to that many results. Defaults to\n10 if not set. Has no effect if a URL is requested.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The pagination token. You may provide the `next_page_token` returned from a\nprevious List request, if any, in order to get the next page. All other\nfields must have the same values as in the previous request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "url": {
	//       "description": "The URL from which to get `ClaimReview` markup. There will be at most one\nresult. If markup is associated with a more canonical version of the URL\nprovided, we will return that URL instead. Cannot be specified along with\nan organization.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/pages",
	//   "response": {
	//     "$ref": "GoogleFactcheckingFactchecktoolsV1alpha1ListClaimReviewMarkupPagesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *PagesListCall) Pages(ctx context.Context, f func(*GoogleFactcheckingFactchecktoolsV1alpha1ListClaimReviewMarkupPagesResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "factchecktools.pages.update":

type PagesUpdateCall struct {
	s                                                             *Service
	name                                                          string
	googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage
	urlParams_                                                    gensupport.URLParams
	ctx_                                                          context.Context
	header_                                                       http.Header
}

// Update: Update for all `ClaimReview` markup on a page
//
// Note that this is a full update. To retain the existing
// `ClaimReview`
// markup on a page, first perform a Get operation, then modify the
// returned
// markup, and finally call Update with the entire `ClaimReview` markup
// as the
// body.
func (r *PagesService) Update(name string, googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage) *PagesUpdateCall {
	c := &PagesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage = googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage
	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 *PagesUpdateCall) Fields(s ...googleapi.Field) *PagesUpdateCall {
	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 *PagesUpdateCall) Context(ctx context.Context) *PagesUpdateCall {
	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 *PagesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PagesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200220")
	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.googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage)
	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, "v1alpha1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "factchecktools.pages.update" call.
// Exactly one of
// *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage.ServerR
// esponse.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 *PagesUpdateCall) Do(opts ...googleapi.CallOption) (*GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage, 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 := &GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage{
		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": "Update for all `ClaimReview` markup on a page\n\nNote that this is a full update. To retain the existing `ClaimReview`\nmarkup on a page, first perform a Get operation, then modify the returned\nmarkup, and finally call Update with the entire `ClaimReview` markup as the\nbody.",
	//   "flatPath": "v1alpha1/pages/{pagesId}",
	//   "httpMethod": "PUT",
	//   "id": "factchecktools.pages.update",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of this `ClaimReview` markup page resource, in the form of\n`pages/{page_id}`. Except for update requests, this field is output-only\nand should not be set by the user.",
	//       "location": "path",
	//       "pattern": "^pages/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "request": {
	//     "$ref": "GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage"
	//   },
	//   "response": {
	//     "$ref": "GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}
