# Copyright (C) 2010 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.

"""Utilities for Google App Engine

Utilities for making it easier to use OAuth 2.0
on Google App Engine.
"""

__author__ = 'jcgregorio@google.com (Joe Gregorio)'

import pickle

from google.appengine.ext import db
from client import Credentials
from client import Flow


class FlowProperty(db.Property):
  """Utility property that allows easy
  storage and retreival of an
  oauth2client.Flow"""

  # Tell what the user type is.
  data_type = Flow

  # For writing to datastore.
  def get_value_for_datastore(self, model_instance):
    flow = super(FlowProperty,
                 self).get_value_for_datastore(model_instance)
    return db.Blob(pickle.dumps(flow))

  # For reading from datastore.
  def make_value_from_datastore(self, value):
    if value is None:
      return None
    return pickle.loads(value)

  def validate(self, value):
    if value is not None and not isinstance(value, Flow):
      raise BadValueError('Property %s must be convertible '
                          'to a FlowThreeLegged instance (%s)' %
                          (self.name, value))
    return super(FlowProperty, self).validate(value)

  def empty(self, value):
    return not value


class CredentialsProperty(db.Property):
  """Utility property that allows easy
  storage and retrieval of
  oath2client.Credentials
  """

  # Tell what the user type is.
  data_type = Credentials

  # For writing to datastore.
  def get_value_for_datastore(self, model_instance):
    cred = super(CredentialsProperty,
                 self).get_value_for_datastore(model_instance)
    return db.Blob(pickle.dumps(cred))

  # For reading from datastore.
  def make_value_from_datastore(self, value):
    if value is None:
      return None
    return pickle.loads(value)

  def validate(self, value):
    if value is not None and not isinstance(value, Credentials):
      raise BadValueError('Property %s must be convertible '
                          'to an Credentials instance (%s)' %
                          (self.name, value))
    return super(CredentialsProperty, self).validate(value)

  def empty(self, value):
    return not value


class StorageByKeyName(object):
  """Store and retrieve a single credential to and from
  the App Engine datastore.

  This Storage helper presumes the Credentials
  have been stored as a CredenialsProperty
  on a datastore model class, and that entities
  are stored by key_name.
  """

  def __init__(self, model, key_name, property_name):
    """Constructor for Storage.

    Args:
      model: db.Model, model class
      key_name: string, key name for the entity that has the credentials
      property_name: string, name of the property that is an CredentialsProperty
    """
    self.model = model
    self.key_name = key_name
    self.property_name = property_name

  def get(self):
    """Retrieve Credential from datastore.

    Returns:
      oauth2client.Credentials
    """
    entity = self.model.get_or_insert(self.key_name)
    credential = getattr(entity, self.property_name)
    if credential and hasattr(credential, 'set_store'):
      credential.set_store(self.put)
    return credential

  def put(self, credentials):
    """Write a Credentials to the datastore.

    Args:
      credentials: Credentials, the credentials to store.
    """
    entity = self.model.get_or_insert(self.key_name)
    setattr(entity, self.property_name, credentials)
    entity.put()
