// 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 groupssettings provides access to the Groups Settings API.
//
// For product documentation, see: https://developers.google.com/google-apps/groups-settings/get_started
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/groupssettings/v1"
//   ...
//   ctx := context.Background()
//   groupssettingsService, err := groupssettings.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:
//
//   groupssettingsService, err := groupssettings.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, ...)
//   groupssettingsService, err := groupssettings.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package groupssettings // import "google.golang.org/api/groupssettings/v1"

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

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

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

const apiId = "groupssettings:v1"
const apiName = "groupssettings"
const apiVersion = "v1"
const basePath = "https://www.googleapis.com/groups/v1/groups/"

// OAuth2 scopes used by this API.
const (
	// View and manage the settings of a G Suite group
	AppsGroupsSettingsScope = "https://www.googleapis.com/auth/apps.groups.settings"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/apps.groups.settings",
	)
	// 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.Groups = NewGroupsService(s)
	return s, nil
}

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

	Groups *GroupsService
}

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

func NewGroupsService(s *Service) *GroupsService {
	rs := &GroupsService{s: s}
	return rs
}

type GroupsService struct {
	s *Service
}

// Groups: JSON template for Group resource
type Groups struct {
	// AllowExternalMembers: Identifies whether members external to your
	// organization can join the group. Possible values are:
	// - true: G Suite users external to your organization can become
	// members of this group.
	// - false: Users not belonging to the organization are not allowed to
	// become members of this group.
	AllowExternalMembers string `json:"allowExternalMembers,omitempty"`

	// AllowGoogleCommunication: Deprecated. Allows Google to contact
	// administrator of the group.
	// - true: Allow Google to contact managers of this group. Occasionally
	// Google may send updates on the latest features, ask for input on new
	// features, or ask for permission to highlight your group.
	// - false: Google can not contact managers of this group.
	AllowGoogleCommunication string `json:"allowGoogleCommunication,omitempty"`

	// AllowWebPosting: Allows posting from web. Possible values are:
	// - true: Allows any member to post to the group forum.
	// - false: Members only use Gmail to communicate with the group.
	AllowWebPosting string `json:"allowWebPosting,omitempty"`

	// ArchiveOnly: Allows the group to be archived only. Possible values
	// are:
	// - true: Group is archived and the group is inactive. New messages to
	// this group are rejected. The older archived messages are browseable
	// and searchable.
	// - If true, the whoCanPostMessage property is set to NONE_CAN_POST.
	//
	// - If reverted from true to false, whoCanPostMessages is set to
	// ALL_MANAGERS_CAN_POST.
	// - false: The group is active and can receive messages.
	// - When false, updating whoCanPostMessage to NONE_CAN_POST, results in
	// an error.
	ArchiveOnly string `json:"archiveOnly,omitempty"`

	// CustomFooterText: Set the content of custom footer text. The maximum
	// number of characters is 1,000.
	CustomFooterText string `json:"customFooterText,omitempty"`

	// CustomReplyTo: An email address used when replying to a message if
	// the replyTo property is set to REPLY_TO_CUSTOM. This address is
	// defined by an account administrator.
	// - When the group's ReplyTo property is set to REPLY_TO_CUSTOM, the
	// customReplyTo property holds a custom email address used when
	// replying to a message.
	// - If the group's ReplyTo property is set to REPLY_TO_CUSTOM, the
	// customReplyTo property must have a text value or an error is
	// returned.
	CustomReplyTo string `json:"customReplyTo,omitempty"`

	// CustomRolesEnabledForSettingsToBeMerged: Specifies whether the group
	// has a custom role that's included in one of the settings being
	// merged. This field is read-only and update/patch requests to it are
	// ignored. Possible values are:
	// - true
	// - false
	CustomRolesEnabledForSettingsToBeMerged string `json:"customRolesEnabledForSettingsToBeMerged,omitempty"`

	// DefaultMessageDenyNotificationText: When a message is rejected, this
	// is text for the rejection notification sent to the message's author.
	// By default, this property is empty and has no value in the API's
	// response body. The maximum notification text size is 10,000
	// characters. Note: Requires sendMessageDenyNotification property to be
	// true.
	DefaultMessageDenyNotificationText string `json:"defaultMessageDenyNotificationText,omitempty"`

	// Description: Description of the group. This property value may be an
	// empty string if no group description has been entered. If entered,
	// the maximum group description is no more than 300 characters.
	Description string `json:"description,omitempty"`

	// Email: The group's email address. This property can be updated using
	// the Directory API. Note: Only a group owner can change a group's
	// email address. A group manager can't do this.
	// When you change your group's address using the Directory API or the
	// control panel, you are changing the address your subscribers use to
	// send email and the web address people use to access your group.
	// People can't reach your group by visiting the old address.
	Email string `json:"email,omitempty"`

	// EnableCollaborativeInbox: Specifies whether a collaborative inbox
	// will remain turned on for the group. Possible values are:
	// - true
	// - false
	EnableCollaborativeInbox string `json:"enableCollaborativeInbox,omitempty"`

	// FavoriteRepliesOnTop: Indicates if favorite replies should be
	// displayed above other replies.
	// - true: Favorite replies will be displayed above other replies.
	// - false: Favorite replies will not be displayed above other replies.
	FavoriteRepliesOnTop string `json:"favoriteRepliesOnTop,omitempty"`

	// IncludeCustomFooter: Whether to include custom footer. Possible
	// values are:
	// - true
	// - false
	IncludeCustomFooter string `json:"includeCustomFooter,omitempty"`

	// IncludeInGlobalAddressList: Enables the group to be included in the
	// Global Address List. For more information, see the help center.
	// Possible values are:
	// - true: Group is included in the Global Address List.
	// - false: Group is not included in the Global Address List.
	IncludeInGlobalAddressList string `json:"includeInGlobalAddressList,omitempty"`

	// IsArchived: Allows the Group contents to be archived. Possible values
	// are:
	// - true: Archive messages sent to the group.
	// - false: Do not keep an archive of messages sent to this group. If
	// false, previously archived messages remain in the archive.
	IsArchived string `json:"isArchived,omitempty"`

	// Kind: The type of the resource. It is always groupsSettings#groups.
	Kind string `json:"kind,omitempty"`

	// MaxMessageBytes: Deprecated. The maximum size of a message is 25Mb.
	MaxMessageBytes int64 `json:"maxMessageBytes,omitempty"`

	// MembersCanPostAsTheGroup: Enables members to post messages as the
	// group. Possible values are:
	// - true: Group member can post messages using the group's email
	// address instead of their own email address. Message appear to
	// originate from the group itself. Note: When true, any message
	// moderation settings on individual users or new members do not apply
	// to posts made on behalf of the group.
	// - false: Members can not post in behalf of the group's email address.
	MembersCanPostAsTheGroup string `json:"membersCanPostAsTheGroup,omitempty"`

	// MessageDisplayFont: Deprecated. The default message display font
	// always has a value of "DEFAULT_FONT".
	MessageDisplayFont string `json:"messageDisplayFont,omitempty"`

	// MessageModerationLevel: Moderation level of incoming messages.
	// Possible values are:
	// - MODERATE_ALL_MESSAGES: All messages are sent to the group owner's
	// email address for approval. If approved, the message is sent to the
	// group.
	// - MODERATE_NON_MEMBERS: All messages from non group members are sent
	// to the group owner's email address for approval. If approved, the
	// message is sent to the group.
	// - MODERATE_NEW_MEMBERS: All messages from new members are sent to the
	// group owner's email address for approval. If approved, the message is
	// sent to the group.
	// - MODERATE_NONE: No moderator approval is required. Messages are
	// delivered directly to the group. Note: When the whoCanPostMessage is
	// set to ANYONE_CAN_POST, we recommend the messageModerationLevel be
	// set to MODERATE_NON_MEMBERS to protect the group from possible
	// spam.
	// When memberCanPostAsTheGroup is true, any message moderation settings
	// on individual users or new members will not apply to posts made on
	// behalf of the group.
	MessageModerationLevel string `json:"messageModerationLevel,omitempty"`

	// Name: Name of the group, which has a maximum size of 75 characters.
	Name string `json:"name,omitempty"`

	// PrimaryLanguage: The primary language for group. For a group's
	// primary language use the language tags from the G Suite languages
	// found at G Suite Email Settings API Email Language Tags.
	PrimaryLanguage string `json:"primaryLanguage,omitempty"`

	// ReplyTo: Specifies who should the default reply go to. Possible
	// values are:
	// - REPLY_TO_CUSTOM: For replies to messages, use the group's custom
	// email address.
	// When the group's ReplyTo property is set to REPLY_TO_CUSTOM, the
	// customReplyTo property holds the custom email address used when
	// replying to a message. If the group's ReplyTo property is set to
	// REPLY_TO_CUSTOM, the customReplyTo property must have a value.
	// Otherwise an error is returned.
	//
	// - REPLY_TO_SENDER: The reply sent to author of message.
	// - REPLY_TO_LIST: This reply message is sent to the group.
	// - REPLY_TO_OWNER: The reply is sent to the owner(s) of the group.
	// This does not include the group's managers.
	// - REPLY_TO_IGNORE: Group users individually decide where the message
	// reply is sent.
	// - REPLY_TO_MANAGERS: This reply message is sent to the group's
	// managers, which includes all managers and the group owner.
	ReplyTo string `json:"replyTo,omitempty"`

	// SendMessageDenyNotification: Allows a member to be notified if the
	// member's message to the group is denied by the group owner. Possible
	// values are:
	// - true: When a message is rejected, send the deny message
	// notification to the message author.
	// The defaultMessageDenyNotificationText property is dependent on the
	// sendMessageDenyNotification property being true.
	//
	// - false: When a message is rejected, no notification is sent.
	SendMessageDenyNotification string `json:"sendMessageDenyNotification,omitempty"`

	// ShowInGroupDirectory: Deprecated. This is merged into the new
	// whoCanDiscoverGroup setting. Allows the group to be visible in the
	// Groups Directory. Possible values are:
	// - true: All groups in the account are listed in the Groups directory.
	//
	// - false: All groups in the account are not listed in the directory.
	ShowInGroupDirectory string `json:"showInGroupDirectory,omitempty"`

	// SpamModerationLevel: Specifies moderation levels for messages
	// detected as spam. Possible values are:
	// - ALLOW: Post the message to the group.
	// - MODERATE: Send the message to the moderation queue. This is the
	// default.
	// - SILENTLY_MODERATE: Send the message to the moderation queue, but do
	// not send notification to moderators.
	// - REJECT: Immediately reject the message.
	SpamModerationLevel string `json:"spamModerationLevel,omitempty"`

	// WhoCanAdd: Deprecated. This is merged into the new
	// whoCanModerateMembers setting. Permissions to add members. Possible
	// values are:
	// - ALL_MEMBERS_CAN_ADD: Managers and members can directly add new
	// members.
	// - ALL_MANAGERS_CAN_ADD: Only managers can directly add new members.
	// this includes the group's owner.
	// - ALL_OWNERS_CAN_ADD: Only owners can directly add new members.
	// - NONE_CAN_ADD: No one can directly add new members.
	WhoCanAdd string `json:"whoCanAdd,omitempty"`

	// WhoCanAddReferences: Deprecated. This functionality is no longer
	// supported in the Google Groups UI. The value is always "NONE".
	WhoCanAddReferences string `json:"whoCanAddReferences,omitempty"`

	// WhoCanApproveMembers: Specifies who can approve members who ask to
	// join groups. This permission will be deprecated once it is merged
	// into the new whoCanModerateMembers setting. Possible values are:
	// - ALL_MEMBERS_CAN_APPROVE
	// - ALL_MANAGERS_CAN_APPROVE
	// - ALL_OWNERS_CAN_APPROVE
	// - NONE_CAN_APPROVE
	WhoCanApproveMembers string `json:"whoCanApproveMembers,omitempty"`

	// WhoCanApproveMessages: Deprecated. This is merged into the new
	// whoCanModerateContent setting. Specifies who can approve pending
	// messages in the moderation queue. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - OWNERS_ONLY
	// - NONE
	WhoCanApproveMessages string `json:"whoCanApproveMessages,omitempty"`

	// WhoCanAssignTopics: Deprecated. This is merged into the new
	// whoCanAssistContent setting. Permission to assign topics in a forum
	// to another user. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - MANAGERS_ONLY
	// - OWNERS_ONLY
	// - NONE
	WhoCanAssignTopics string `json:"whoCanAssignTopics,omitempty"`

	// WhoCanAssistContent: Specifies who can moderate metadata. Possible
	// values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - MANAGERS_ONLY
	// - OWNERS_ONLY
	// - NONE
	WhoCanAssistContent string `json:"whoCanAssistContent,omitempty"`

	// WhoCanBanUsers: Specifies who can deny membership to users. This
	// permission will be deprecated once it is merged into the new
	// whoCanModerateMembers setting. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - OWNERS_ONLY
	// - NONE
	WhoCanBanUsers string `json:"whoCanBanUsers,omitempty"`

	// WhoCanContactOwner: Permission to contact owner of the group via web
	// UI. Possible values are:
	// - ALL_IN_DOMAIN_CAN_CONTACT
	// - ALL_MANAGERS_CAN_CONTACT
	// - ALL_MEMBERS_CAN_CONTACT
	// - ANYONE_CAN_CONTACT
	WhoCanContactOwner string `json:"whoCanContactOwner,omitempty"`

	// WhoCanDeleteAnyPost: Deprecated. This is merged into the new
	// whoCanModerateContent setting. Specifies who can delete replies to
	// topics. (Authors can always delete their own posts). Possible values
	// are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - OWNERS_ONLY
	// - NONE
	WhoCanDeleteAnyPost string `json:"whoCanDeleteAnyPost,omitempty"`

	// WhoCanDeleteTopics: Deprecated. This is merged into the new
	// whoCanModerateContent setting. Specifies who can delete topics.
	// Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - OWNERS_ONLY
	// - NONE
	WhoCanDeleteTopics string `json:"whoCanDeleteTopics,omitempty"`

	// WhoCanDiscoverGroup: Specifies the set of users for whom this group
	// is discoverable. Possible values are:
	// - ANYONE_CAN_DISCOVER
	// - ALL_IN_DOMAIN_CAN_DISCOVER
	// - ALL_MEMBERS_CAN_DISCOVER
	WhoCanDiscoverGroup string `json:"whoCanDiscoverGroup,omitempty"`

	// WhoCanEnterFreeFormTags: Deprecated. This is merged into the new
	// whoCanAssistContent setting. Permission to enter free form tags for
	// topics in a forum. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - MANAGERS_ONLY
	// - OWNERS_ONLY
	// - NONE
	WhoCanEnterFreeFormTags string `json:"whoCanEnterFreeFormTags,omitempty"`

	// WhoCanHideAbuse: Deprecated. This is merged into the new
	// whoCanModerateContent setting. Specifies who can hide posts by
	// reporting them as abuse. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - OWNERS_ONLY
	// - NONE
	WhoCanHideAbuse string `json:"whoCanHideAbuse,omitempty"`

	// WhoCanInvite: Deprecated. This is merged into the new
	// whoCanModerateMembers setting. Permissions to invite new members.
	// Possible values are:
	// - ALL_MEMBERS_CAN_INVITE: Managers and members can invite a new
	// member candidate.
	// - ALL_MANAGERS_CAN_INVITE: Only managers can invite a new member.
	// This includes the group's owner.
	// - ALL_OWNERS_CAN_INVITE: Only owners can invite a new member.
	// - NONE_CAN_INVITE: No one can invite a new member candidate.
	WhoCanInvite string `json:"whoCanInvite,omitempty"`

	// WhoCanJoin: Permission to join group. Possible values are:
	// - ANYONE_CAN_JOIN: Anyone in the account domain can join. This
	// includes accounts with multiple domains.
	// - ALL_IN_DOMAIN_CAN_JOIN: Any Internet user who is outside your
	// domain can access your Google Groups service and view the list of
	// groups in your Groups directory. Warning: Group owners can add
	// external addresses, outside of the domain to their groups. They can
	// also allow people outside your domain to join their groups. If you
	// later disable this option, any external addresses already added to
	// users' groups remain in those groups.
	// - INVITED_CAN_JOIN: Candidates for membership can be invited to join.
	//
	// - CAN_REQUEST_TO_JOIN: Non members can request an invitation to join.
	WhoCanJoin string `json:"whoCanJoin,omitempty"`

	// WhoCanLeaveGroup: Permission to leave the group. Possible values are:
	//
	// - ALL_MANAGERS_CAN_LEAVE
	// - ALL_MEMBERS_CAN_LEAVE
	// - NONE_CAN_LEAVE
	WhoCanLeaveGroup string `json:"whoCanLeaveGroup,omitempty"`

	// WhoCanLockTopics: Deprecated. This is merged into the new
	// whoCanModerateContent setting. Specifies who can prevent users from
	// posting replies to topics. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - OWNERS_ONLY
	// - NONE
	WhoCanLockTopics string `json:"whoCanLockTopics,omitempty"`

	// WhoCanMakeTopicsSticky: Deprecated. This is merged into the new
	// whoCanModerateContent setting. Specifies who can make topics appear
	// at the top of the topic list. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - OWNERS_ONLY
	// - NONE
	WhoCanMakeTopicsSticky string `json:"whoCanMakeTopicsSticky,omitempty"`

	// WhoCanMarkDuplicate: Deprecated. This is merged into the new
	// whoCanAssistContent setting. Permission to mark a topic as a
	// duplicate of another topic. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - MANAGERS_ONLY
	// - OWNERS_ONLY
	// - NONE
	WhoCanMarkDuplicate string `json:"whoCanMarkDuplicate,omitempty"`

	// WhoCanMarkFavoriteReplyOnAnyTopic: Deprecated. This is merged into
	// the new whoCanAssistContent setting. Permission to mark any other
	// user's post as a favorite reply. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - MANAGERS_ONLY
	// - OWNERS_ONLY
	// - NONE
	WhoCanMarkFavoriteReplyOnAnyTopic string `json:"whoCanMarkFavoriteReplyOnAnyTopic,omitempty"`

	// WhoCanMarkFavoriteReplyOnOwnTopic: Deprecated. This is merged into
	// the new whoCanAssistContent setting. Permission to mark a post for a
	// topic they started as a favorite reply. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - MANAGERS_ONLY
	// - OWNERS_ONLY
	// - NONE
	WhoCanMarkFavoriteReplyOnOwnTopic string `json:"whoCanMarkFavoriteReplyOnOwnTopic,omitempty"`

	// WhoCanMarkNoResponseNeeded: Deprecated. This is merged into the new
	// whoCanAssistContent setting. Permission to mark a topic as not
	// needing a response. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - MANAGERS_ONLY
	// - OWNERS_ONLY
	// - NONE
	WhoCanMarkNoResponseNeeded string `json:"whoCanMarkNoResponseNeeded,omitempty"`

	// WhoCanModerateContent: Specifies who can moderate content. Possible
	// values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - OWNERS_ONLY
	// - NONE
	WhoCanModerateContent string `json:"whoCanModerateContent,omitempty"`

	// WhoCanModerateMembers: Specifies who can manage members. Possible
	// values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - OWNERS_ONLY
	// - NONE
	WhoCanModerateMembers string `json:"whoCanModerateMembers,omitempty"`

	// WhoCanModifyMembers: Deprecated. This is merged into the new
	// whoCanModerateMembers setting. Specifies who can change group
	// members' roles. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - OWNERS_ONLY
	// - NONE
	WhoCanModifyMembers string `json:"whoCanModifyMembers,omitempty"`

	// WhoCanModifyTagsAndCategories: Deprecated. This is merged into the
	// new whoCanAssistContent setting. Permission to change tags and
	// categories. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - MANAGERS_ONLY
	// - OWNERS_ONLY
	// - NONE
	WhoCanModifyTagsAndCategories string `json:"whoCanModifyTagsAndCategories,omitempty"`

	// WhoCanMoveTopicsIn: Deprecated. This is merged into the new
	// whoCanModerateContent setting. Specifies who can move topics into the
	// group or forum. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - OWNERS_ONLY
	// - NONE
	WhoCanMoveTopicsIn string `json:"whoCanMoveTopicsIn,omitempty"`

	// WhoCanMoveTopicsOut: Deprecated. This is merged into the new
	// whoCanModerateContent setting. Specifies who can move topics out of
	// the group or forum. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - OWNERS_ONLY
	// - NONE
	WhoCanMoveTopicsOut string `json:"whoCanMoveTopicsOut,omitempty"`

	// WhoCanPostAnnouncements: Deprecated. This is merged into the new
	// whoCanModerateContent setting. Specifies who can post announcements,
	// a special topic type. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - OWNERS_ONLY
	// - NONE
	WhoCanPostAnnouncements string `json:"whoCanPostAnnouncements,omitempty"`

	// WhoCanPostMessage: Permissions to post messages. Possible values are:
	//
	// - NONE_CAN_POST: The group is disabled and archived. No one can post
	// a message to this group.
	// - When archiveOnly is false, updating whoCanPostMessage to
	// NONE_CAN_POST, results in an error.
	// - If archiveOnly is reverted from true to false, whoCanPostMessages
	// is set to ALL_MANAGERS_CAN_POST.
	// - ALL_MANAGERS_CAN_POST: Managers, including group owners, can post
	// messages.
	// - ALL_MEMBERS_CAN_POST: Any group member can post a message.
	// - ALL_OWNERS_CAN_POST: Only group owners can post a message.
	// - ALL_IN_DOMAIN_CAN_POST: Anyone in the account can post a message.
	//
	// - ANYONE_CAN_POST: Any Internet user who outside your account can
	// access your Google Groups service and post a message. Note: When
	// whoCanPostMessage is set to ANYONE_CAN_POST, we recommend the
	// messageModerationLevel be set to MODERATE_NON_MEMBERS to protect the
	// group from possible spam.
	WhoCanPostMessage string `json:"whoCanPostMessage,omitempty"`

	// WhoCanTakeTopics: Deprecated. This is merged into the new
	// whoCanAssistContent setting. Permission to take topics in a forum.
	// Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - MANAGERS_ONLY
	// - OWNERS_ONLY
	// - NONE
	WhoCanTakeTopics string `json:"whoCanTakeTopics,omitempty"`

	// WhoCanUnassignTopic: Deprecated. This is merged into the new
	// whoCanAssistContent setting. Permission to unassign any topic in a
	// forum. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - MANAGERS_ONLY
	// - OWNERS_ONLY
	// - NONE
	WhoCanUnassignTopic string `json:"whoCanUnassignTopic,omitempty"`

	// WhoCanUnmarkFavoriteReplyOnAnyTopic: Deprecated. This is merged into
	// the new whoCanAssistContent setting. Permission to unmark any post
	// from a favorite reply. Possible values are:
	// - ALL_MEMBERS
	// - OWNERS_AND_MANAGERS
	// - MANAGERS_ONLY
	// - OWNERS_ONLY
	// - NONE
	WhoCanUnmarkFavoriteReplyOnAnyTopic string `json:"whoCanUnmarkFavoriteReplyOnAnyTopic,omitempty"`

	// WhoCanViewGroup: Permissions to view group messages. Possible values
	// are:
	// - ANYONE_CAN_VIEW: Any Internet user can view the group's messages.
	//
	// - ALL_IN_DOMAIN_CAN_VIEW: Anyone in your account can view this
	// group's messages.
	// - ALL_MEMBERS_CAN_VIEW: All group members can view the group's
	// messages.
	// - ALL_MANAGERS_CAN_VIEW: Any group manager can view this group's
	// messages.
	WhoCanViewGroup string `json:"whoCanViewGroup,omitempty"`

	// WhoCanViewMembership: Permissions to view membership. Possible values
	// are:
	// - ALL_IN_DOMAIN_CAN_VIEW: Anyone in the account can view the group
	// members list.
	// If a group already has external members, those members can still send
	// email to this group.
	//
	// - ALL_MEMBERS_CAN_VIEW: The group members can view the group members
	// list.
	// - ALL_MANAGERS_CAN_VIEW: The group managers can view group members
	// list.
	WhoCanViewMembership string `json:"whoCanViewMembership,omitempty"`

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

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

// method id "groupsSettings.groups.get":

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

// Get: Gets one resource by id.
func (r *GroupsService) Get(groupUniqueId string) *GroupsGetCall {
	c := &GroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.groupUniqueId = groupUniqueId
	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 *GroupsGetCall) Fields(s ...googleapi.Field) *GroupsGetCall {
	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 *GroupsGetCall) IfNoneMatch(entityTag string) *GroupsGetCall {
	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 *GroupsGetCall) Context(ctx context.Context) *GroupsGetCall {
	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 *GroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "groupsSettings.groups.get" call.
// Exactly one of *Groups or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Groups.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 *GroupsGetCall) Do(opts ...googleapi.CallOption) (*Groups, 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 := &Groups{
		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": "Gets one resource by id.",
	//   "httpMethod": "GET",
	//   "id": "groupsSettings.groups.get",
	//   "parameterOrder": [
	//     "groupUniqueId"
	//   ],
	//   "parameters": {
	//     "groupUniqueId": {
	//       "description": "The group's email address.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{groupUniqueId}",
	//   "response": {
	//     "$ref": "Groups"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/apps.groups.settings"
	//   ]
	// }

}

// method id "groupsSettings.groups.patch":

type GroupsPatchCall struct {
	s             *Service
	groupUniqueId string
	groups        *Groups
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Patch: Updates an existing resource. This method supports patch
// semantics.
func (r *GroupsService) Patch(groupUniqueId string, groups *Groups) *GroupsPatchCall {
	c := &GroupsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.groupUniqueId = groupUniqueId
	c.groups = groups
	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 *GroupsPatchCall) Fields(s ...googleapi.Field) *GroupsPatchCall {
	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 *GroupsPatchCall) Context(ctx context.Context) *GroupsPatchCall {
	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 *GroupsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "groupsSettings.groups.patch" call.
// Exactly one of *Groups or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Groups.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 *GroupsPatchCall) Do(opts ...googleapi.CallOption) (*Groups, 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 := &Groups{
		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 an existing resource. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "groupsSettings.groups.patch",
	//   "parameterOrder": [
	//     "groupUniqueId"
	//   ],
	//   "parameters": {
	//     "groupUniqueId": {
	//       "description": "The group's email address.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{groupUniqueId}",
	//   "request": {
	//     "$ref": "Groups"
	//   },
	//   "response": {
	//     "$ref": "Groups"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/apps.groups.settings"
	//   ]
	// }

}

// method id "groupsSettings.groups.update":

type GroupsUpdateCall struct {
	s             *Service
	groupUniqueId string
	groups        *Groups
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Update: Updates an existing resource.
func (r *GroupsService) Update(groupUniqueId string, groups *Groups) *GroupsUpdateCall {
	c := &GroupsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.groupUniqueId = groupUniqueId
	c.groups = groups
	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 *GroupsUpdateCall) Fields(s ...googleapi.Field) *GroupsUpdateCall {
	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 *GroupsUpdateCall) Context(ctx context.Context) *GroupsUpdateCall {
	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 *GroupsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "groupsSettings.groups.update" call.
// Exactly one of *Groups or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Groups.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 *GroupsUpdateCall) Do(opts ...googleapi.CallOption) (*Groups, 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 := &Groups{
		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 an existing resource.",
	//   "httpMethod": "PUT",
	//   "id": "groupsSettings.groups.update",
	//   "parameterOrder": [
	//     "groupUniqueId"
	//   ],
	//   "parameters": {
	//     "groupUniqueId": {
	//       "description": "The group's email address.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{groupUniqueId}",
	//   "request": {
	//     "$ref": "Groups"
	//   },
	//   "response": {
	//     "$ref": "Groups"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/apps.groups.settings"
	//   ]
	// }

}
