#!/usr/bin/python
#
# Copyright 2014 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Sample for the Group Settings API demonstrates get and update method.

Usage:
  $ python groupsettings.py

You can also get help on all the command-line flags the program understands
by running:

  $ python groupsettings.py --help
"""
from __future__ import print_function

__author__ = 'Shraddha Gupta <shraddhag@google.com>'

from optparse import OptionParser
import os

import pprint
import sys
from googleapiclient.discovery import build
import httplib2
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client.tools import run


# CLIENT_SECRETS, name of a file containing the OAuth 2.0 information for this
# application, including client_id and client_secret, which are found
# on the API Access tab on the Google APIs
# Console <http://code.google.com/apis/console>
CLIENT_SECRETS = 'client_secrets.json'

# Helpful message to display in the browser if the CLIENT_SECRETS file
# is missing.
MISSING_CLIENT_SECRETS_MESSAGE = """
WARNING: Please configure OAuth 2.0

To make this sample run you will need to populate the client_secrets.json file
found at:

   %s

with information from the APIs Console <https://code.google.com/apis/console>.

""" % os.path.join(os.path.dirname(__file__), CLIENT_SECRETS)


def access_settings(service, groupId, settings):
  """Retrieves a group's settings and updates the access permissions to it.

  Args:
    service: object service for the Group Settings API.
    groupId: string identifier of the group@domain.
    settings: dictionary key-value pairs of properties of group.
  """

  # Get the resource 'group' from the set of resources of the API.
  # The Group Settings API has only one resource 'group'.
  group = service.groups()

  # Retrieve the group properties
  g = group.get(groupUniqueId=groupId).execute()
  print('\nGroup properties for group %s\n' % g['name'])
  pprint.pprint(g)

  # If dictionary is empty, return without updating the properties.
  if not settings.keys():
    print('\nGive access parameters to update group access permissions\n')
    return

  body = {}

  # Settings might contain null value for some keys(properties). 
  # Extract the properties with values and add to dictionary body.
  for key in settings.iterkeys():
    if settings[key] is not None:
      body[key] = settings[key]

  # Update the properties of group
  g1 = group.update(groupUniqueId=groupId, body=body).execute()

  print('\nUpdated Access Permissions to the group\n')
  pprint.pprint(g1)


def main(argv):
  """Demos the setting of the access properties by the Groups Settings API."""
  usage = 'usage: %prog [options]'
  parser = OptionParser(usage=usage)
  parser.add_option('--groupId',
                    help='Group email address')
  parser.add_option('--whoCanInvite',
                    help='Possible values: ALL_MANAGERS_CAN_INVITE, '
                    'ALL_MEMBERS_CAN_INVITE')
  parser.add_option('--whoCanJoin',
                    help='Possible values: ALL_IN_DOMAIN_CAN_JOIN, '
                    'ANYONE_CAN_JOIN, CAN_REQUEST_TO_JOIN, '
                    'CAN_REQUEST_TO_JOIN')
  parser.add_option('--whoCanPostMessage',
                    help='Possible values: ALL_IN_DOMAIN_CAN_POST, '
                    'ALL_MANAGERS_CAN_POST, ALL_MEMBERS_CAN_POST, '
                    'ANYONE_CAN_POST, NONE_CAN_POST')
  parser.add_option('--whoCanViewGroup',
                    help='Possible values: ALL_IN_DOMAIN_CAN_VIEW, '
                    'ALL_MANAGERS_CAN_VIEW, ALL_MEMBERS_CAN_VIEW, '
                    'ANYONE_CAN_VIEW')
  parser.add_option('--whoCanViewMembership',
                    help='Possible values: ALL_IN_DOMAIN_CAN_VIEW, '
                    'ALL_MANAGERS_CAN_VIEW, ALL_MEMBERS_CAN_VIEW, '
                    'ANYONE_CAN_VIEW')
  (options, args) = parser.parse_args()

  if options.groupId is None:
    print('Give the groupId for the group')
    parser.print_help()
    return

  settings = {}

  if (options.whoCanInvite or options.whoCanJoin or options.whoCanPostMessage
      or options.whoCanPostMessage or options.whoCanViewMembership) is None:
    print('No access parameters given in input to update access permissions')
    parser.print_help()
  else:
    settings = {'whoCanInvite': options.whoCanInvite,
                'whoCanJoin': options.whoCanJoin,
                'whoCanPostMessage': options.whoCanPostMessage,
                'whoCanViewGroup': options.whoCanViewGroup,
                'whoCanViewMembership': options.whoCanViewMembership}

  # Set up a Flow object to be used if we need to authenticate.
  FLOW = flow_from_clientsecrets(CLIENT_SECRETS,
      scope='https://www.googleapis.com/auth/apps.groups.settings',
      message=MISSING_CLIENT_SECRETS_MESSAGE)

  storage = Storage('groupsettings.dat')
  credentials = storage.get()

  if credentials is None or credentials.invalid:
    print('invalid credentials')
    # Save the credentials in storage to be used in subsequent runs.
    credentials = run(FLOW, storage)

  # Create an httplib2.Http object to handle our HTTP requests and authorize it
  # with our good Credentials.
  http = httplib2.Http()
  http = credentials.authorize(http)

  service = build('groupssettings', 'v1', http=http)

  access_settings(service=service, groupId=options.groupId, settings=settings)

if __name__ == '__main__':
  main(sys.argv)
