text: # Copyright 2015 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.
  
  """Utility for managing projects via the Cloud Resource Manager API."""
  
  
  from google.cloud.exceptions import NotFound
  
  
  class Project(object):
      """Projects are containers for your work on Google Cloud Platform.
  
      .. note::
  
          A :class:`Project` can also be created via
          :meth:`Client.new_project() \
          <google.cloud.resource_manager.client.Client.new_project>`
  
      To manage labels on a :class:`Project`::
  
          >>> from google.cloud import resource_manager
          >>> client = resource_manager.Client()
          >>> project = client.new_project('purple-spaceship-123')
          >>> project.labels = {'color': 'purple'}
          >>> project.labels['environment'] = 'production'
          >>> project.update()
  
      See:
      https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects
  
      :type project_id: str
      :param project_id: The globally unique ID of the project.
  
      :type client: :class:`google.cloud.resource_manager.client.Client`
      :param client: The Client used with this project.
  
      :type name: str
      :param name: The display name of the project.
  
      :type labels: dict
      :param labels: A list of labels associated with the project.
      """
      def __init__(self, project_id, client, name=None, labels=None):
          self._client = client
          self.project_id = project_id
          self.name = name
          self.number = None
          self.labels = labels or {}
          self.status = None
          self.parent = None
  
      def __repr__(self):
          return '<Project: %r (%r)>' % (self.name, self.project_id)
  
      @classmethod
      def from_api_repr(cls, resource, client):
          """Factory:  construct a project given its API representation.
  
          :type resource: dict
          :param resource: project resource representation returned from the API
  
          :type client: :class:`google.cloud.resource_manager.client.Client`
          :param client: The Client used with this project.
  
          :rtype: :class:`google.cloud.resource_manager.project.Project`
          :returns: The project created.
          """
          project = cls(project_id=resource['projectId'], client=client)
          project.set_properties_from_api_repr(resource)
          return project
  
      def set_properties_from_api_repr(self, resource):
          """Update specific properties from its API representation."""
          self.name = resource.get('name')
          self.number = resource['projectNumber']
          self.labels = resource.get('labels', {})
          self.status = resource['lifecycleState']
          if 'parent' in resource:
              self.parent = resource['parent']
  
      @property
      def full_name(self):
          """Fully-qualified name (ie, ``'projects/purple-spaceship-123'``)."""
          if not self.project_id:
              raise ValueError('Missing project ID.')
          return 'projects/%s' % (self.project_id)
  
      @property
      def path(self):
          """URL for the project (ie, ``'/projects/purple-spaceship-123'``)."""
          return '/%s' % (self.full_name)
  
      def _require_client(self, client):
          """Check client or verify over-ride.
  
          :type client: :class:`google.cloud.resource_manager.client.Client` or
                        ``NoneType``
          :param client: the client to use.  If not passed, falls back to the
                         ``client`` stored on the current project.
  
          :rtype: :class:`google.cloud.resource_manager.client.Client`
          :returns: The client passed in or the currently bound client.
          """
          if client is None:
              client = self._client
          return client
  
      def create(self, client=None):
          """API call:  create the project via a ``POST`` request.
  
          See
          https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/create
  
          :type client: :class:`google.cloud.resource_manager.client.Client` or
                        :data:`NoneType <types.NoneType>`
          :param client: the client to use.  If not passed, falls back to
                         the client stored on the current project.
          """
          client = self._require_client(client)
  
          data = {
              'projectId': self.project_id,
              'name': self.name,
              'labels': self.labels,
          }
          resp = client._connection.api_request(method='POST', path='/projects',
                                                data=data)
          self.set_properties_from_api_repr(resource=resp)
  
      def reload(self, client=None):
          """API call:  reload the project via a ``GET`` request.
  
          This method will reload the newest metadata for the project. If you've
          created a new :class:`Project` instance via
          :meth:`Client.new_project() \
          <google.cloud.resource_manager.client.Client.new_project>`,
          this method will retrieve project metadata.
  
          .. warning::
  
              This will overwrite any local changes you've made and not saved
              via :meth:`update`.
  
          See
          https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/get
  
          :type client: :class:`google.cloud.resource_manager.client.Client` or
                        :data:`NoneType <types.NoneType>`
          :param client: the client to use.  If not passed, falls back to
                         the client stored on the current project.
          """
          client = self._require_client(client)
  
          # We assume the project exists. If it doesn't it will raise a NotFound
          # exception.
          resp = client._connection.api_request(method='GET', path=self.path)
          self.set_properties_from_api_repr(resource=resp)
  
      def exists(self, client=None):
          """API call:  test the existence of a project via a ``GET`` request.
  
          See
          https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/get
  
          :type client: :class:`google.cloud.resource_manager.client.Client` or
                        :data:`NoneType <types.NoneType>`
          :param client: the client to use.  If not passed, falls back to
                         the client stored on the current project.
  
          :rtype: bool
          :returns: Boolean indicating existence of the project.
          """
          client = self._require_client(client)
  
          try:
              # Note that we have to request the entire resource as the API
              # doesn't provide a way tocheck for existence only.
              client._connection.api_request(method='GET', path=self.path)
          except NotFound:
              return False
          else:
              return True
  
      def update(self, client=None):
          """API call:  update the project via a ``PUT`` request.
  
          See
          https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/update
  
          :type client: :class:`google.cloud.resource_manager.client.Client` or
                        :data:`NoneType <types.NoneType>`
          :param client: the client to use.  If not passed, falls back to
                         the client stored on the current project.
          """
          client = self._require_client(client)
  
          data = {
              'name': self.name,
              'labels': self.labels,
              'parent': self.parent,
          }
  
          resp = client._connection.api_request(
              method='PUT', path=self.path, data=data)
          self.set_properties_from_api_repr(resp)
  
      def delete(self, client=None, reload_data=False):
          """API call:  delete the project via a ``DELETE`` request.
  
          See:
          https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/delete
  
          This actually changes the status (``lifecycleState``) from ``ACTIVE``
          to ``DELETE_REQUESTED``.
          Later (it's not specified when), the project will move into the
          ``DELETE_IN_PROGRESS`` state, which means the deleting has actually
          begun.
  
          :type client: :class:`google.cloud.resource_manager.client.Client` or
                        :data:`NoneType <types.NoneType>`
          :param client: the client to use.  If not passed, falls back to
                         the client stored on the current project.
  
          :type reload_data: bool
          :param reload_data: Whether to reload the project with the latest
                              state. If you want to get the updated status,
                              you'll want this set to :data:`True` as the DELETE
                              method doesn't send back the updated project.
                              Default: :data:`False`.
          """
          client = self._require_client(client)
          client._connection.api_request(method='DELETE', path=self.path)
  
          # If the reload flag is set, reload the project.
          if reload_data:
              self.reload()
  
      def undelete(self, client=None, reload_data=False):
          """API call:  undelete the project via a ``POST`` request.
  
          See
          https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/undelete
  
          This actually changes the project status (``lifecycleState``) from
          ``DELETE_REQUESTED`` to ``ACTIVE``.
          If the project has already reached a status of ``DELETE_IN_PROGRESS``,
          this request will fail and the project cannot be restored.
  
          :type client: :class:`google.cloud.resource_manager.client.Client` or
                        :data:`NoneType <types.NoneType>`
          :param client: the client to use.  If not passed, falls back to
                         the client stored on the current project.
  
          :type reload_data: bool
          :param reload_data: Whether to reload the project with the latest
                              state. If you want to get the updated status,
                              you'll want this set to :data:`True` as the DELETE
                              method doesn't send back the updated project.
                              Default: :data:`False`.
          """
          client = self._require_client(client)
          client._connection.api_request(
              method='POST', path=self.path + ':undelete')
  
          # If the reload flag is set, reload the project.
          if reload_data:
              self.reload()
  