# Copyright 2014 Google Inc.
#
# 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.

"""Manipulate access control lists that Cloud Storage provides.

:class:`google.cloud.storage.bucket.Bucket` has a getting method that creates
an ACL object under the hood, and you can interact with that using
:func:`google.cloud.storage.bucket.Bucket.acl`:

.. literalinclude:: storage_snippets.py
    :start-after: [START client_bucket_acl]
    :end-before: [END client_bucket_acl]


Adding and removing permissions can be done with the following methods
(in increasing order of granularity):

- :func:`ACL.all`
  corresponds to access for all users.
- :func:`ACL.all_authenticated` corresponds
  to access for all users that are signed into a Google account.
- :func:`ACL.domain` corresponds to access on a
  per Google Apps domain (ie, ``example.com``).
- :func:`ACL.group` corresponds to access on a
  per group basis (either by ID or e-mail address).
- :func:`ACL.user` corresponds to access on a
  per user basis (either by ID or e-mail address).

And you are able to ``grant`` and ``revoke`` the following roles:

- **Reading**:
  :func:`_ACLEntity.grant_read` and :func:`_ACLEntity.revoke_read`
- **Writing**:
  :func:`_ACLEntity.grant_write` and :func:`_ACLEntity.revoke_write`
- **Owning**:
  :func:`_ACLEntity.grant_owner` and :func:`_ACLEntity.revoke_owner`

You can use any of these like any other factory method (these happen to
be :class:`_ACLEntity` factories):

.. literalinclude:: storage_snippets.py
   :start-after: [START acl_user_settings]
   :end-before: [END acl_user_settings]

You can also chain these ``grant_*`` and ``revoke_*`` methods together
for brevity:

.. literalinclude:: storage_snippets.py
   :start-after: [START acl_revoke_write]
   :end-before: [END acl_revoke_write]

After that, you can save any changes you make with the
:func:`google.cloud.storage.acl.ACL.save` method:

.. literalinclude:: storage_snippets.py
   :start-after: [START acl_save]
   :end-before: [END acl_save]

You can alternatively save any existing :class:`google.cloud.storage.acl.ACL`
object (whether it was created by a factory method or not) from a
:class:`google.cloud.storage.bucket.Bucket`:

.. literalinclude:: storage_snippets.py
   :start-after: [START acl_save_bucket]
   :end-before: [END acl_save_bucket]

To get the list of ``entity`` and ``role`` for each unique pair, the
:class:`ACL` class is iterable:

.. literalinclude:: storage_snippets.py
   :start-after: [START acl_print]
   :end-before: [END acl_print]

This list of tuples can be used as the ``entity`` and ``role`` fields
when sending metadata for ACLs to the API.
"""


class _ACLEntity(object):
    """Class representing a set of roles for an entity.

    This is a helper class that you likely won't ever construct
    outside of using the factor methods on the :class:`ACL` object.

    :type entity_type: str
    :param entity_type: The type of entity (ie, 'group' or 'user').

    :type identifier: str
    :param identifier: The ID or e-mail of the entity. For the special
                       entity types (like 'allUsers') this is optional.
    """