// 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 receives the default reply. 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/20200710")
	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/20200710")
	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/20200710")
	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"
	//   ]
	// }

}
