# 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.

"""Multi-credential file store with lock support.

This module implements a JSON credential store where multiple
credentials can be stored in one file. That file supports locking
both in a single process and across processes.

The credential themselves are keyed off of:

* client_id
* user_agent
* scope

The format of the stored data is like so::

  {
    'file_version': 1,
    'data': [
      {
        'key': {
          'clientId': '<client id>',
          'userAgent': '<user agent>',
          'scope': '<scope>'
        },
        'credential': {
          # JSON serialized Credentials.
        }
      }
    ]
  }

"""

__author__ = 'jbeda@google.com (Joe Beda)'

import errno
import json
import logging
import os
import threading

from .client import Credentials
from .client import Storage as BaseStorage
from . import util
from locked_file import LockedFile

logger = logging.getLogger(__name__)

# A dict from 'filename'->_MultiStore instances
_multistores = {}
_multistores_lock = threading.Lock()


class Error(Exception):
  """Base error for this module."""


class NewerCredentialStoreError(Error):
  """The credential store is a newer version than supported."""


@util.positional(4)
def get_credential_storage(filename, client_id, user_agent, scope,
                           warn_on_readonly=True):
  """Get a Storage instance for a credential.

  Args:
    filename: The JSON file storing a set of credentials
    client_id: The client_id for the credential
    user_agent: The user agent for the credential
    scope: string or iterable of strings, Scope(s) being requested
    warn_on_readonly: if True, log a warning if the store is readonly

  Returns:
    An object derived from client.Storage for getting/setting the
    credential.
  """
  # Recreate the legacy key with these specific parameters
  key = {'clientId': client_id, 'userAgent': user_agent,
         'scope': util.scopes_to_string(scope)}
  return get_credential_storage_custom_key(
      filename, key, warn_on_readonly=warn_on_readonly)


@util.positional(2)
def get_credential_storage_custom_string_key(
    filename, key_string, warn_on_readonly=True):
  """Get a Storage instance for a credential using a single string as a key.

  Allows you to provide a string as a custom key that will be used for
  credential storage and retrieval.

  Args:
    filename: The JSON file storing a set of credentials
    key_string: A string to use as the key for storing this credential.
    warn_on_readonly: if True, log a warning if the store is readonly

  Returns:
    An object derived from client.Storage for getting/setting the
    credential.
  """
  # Create a key dictionary that can be used
  key_dict = {'key': key_string}
  return get_credential_storage_custom_key(
      filename, key_dict, warn_on_readonly=warn_on_readonly)


@util.positional(2)
def get_credential_storage_custom_key(
    filename, key_dict, warn_on_readonly=True):
  """Get a Storage instance for a credential using a dictionary as a key.

  Allows you to provide a dictionary as a custom key that will be used for
  credential storage and retrieval.

  Args:
    filename: The JSON file storing a set of credentials
    key_dict: A dictionary to use as the key for storing this credential. There
      is no ordering of the keys in the dictionary. Logically equivalent
      dictionaries will produce equivalent storage keys.
    warn_on_readonly: if True, log a warning if the store is readonly

  Returns:
    An object derived from client.Storage for getting/setting the
    credential.
  """
  multistore = _get_multistore(filename, warn_on_readonly=warn_on_readonly)
  key = util.dict_to_tuple_key(key_dict)
  return multistore._get_storage(key)


@util.positional(1)
def get_all_credential_keys(filename, warn_on_readonly=True):
  """Gets all the registered credential keys in the given Multistore.

  Args:
    filename: The JSON file storing a set of credentials
    warn_on_readonly: if True, log a warning if the store is readonly

  Returns:
    A list of the credential keys present in the file.  They are returned as
    dictionaries that can be passed into get_credential_storage_custom_key to
    get the actual credentials.
  """
  multistore = _get_multistore(filename, warn_on_readonly=warn_on_readonly)
  multistore._lock()
  try:
    return multistore._get_all_credential_keys()
  finally:
    multistore._unlock()


@util.positional(1)
def _get_multistore(filename, warn_on_readonly=True):
  """A helper method to initialize the multistore with proper locking.

  Args:
    filename: The JSON file storing a set of credentials
    warn_on_readonly: if True, log a warning if the store is readonly

  Returns:
    A multistore object
  """
  filename = os.path.expanduser(filename)
  _multistores_lock.acquire()
  try:
    multistore = _multistores.setdefault(
        filename, _MultiStore(filename, warn_on_readonly=warn_on_readonly))
  finally:
    _multistores_lock.release()
  return multistore


class _MultiStore(object):
  """A file backed store for multiple credentials."""

  @util.positional(2)
  def __init__(self, filename, warn_on_readonly=True):
    """Initialize the class.

    This will create the file if necessary.
    """
    self._file = LockedFile(filename, 'r+', 'r')
    self._thread_lock = threading.Lock()
    self._read_only = False
    self._warn_on_readonly = warn_on_readonly

    self._create_file_if_needed()

    # Cache of deserialized store. This is only valid after the
    # _MultiStore is locked or _refresh_data_cache is called. This is
    # of the form of:
    #
    # ((key, value), (key, value)...) -> OAuth2Credential
    #
    # If this is None, then the store hasn't been read yet.
    self._data = None

  class _Storage(BaseStorage):
    """A Storage object that knows how to read/write a single credential."""

    def __init__(self, multistore, key):
      self._multistore = multistore
      self._key = key

    def acquire_lock(self):
      """Acquires any lock necessary to access this Storage.

      This lock is not reentrant.
      """
      self._multistore._lock()

    def release_lock(self):
      """Release the Storage lock.

      Trying to release a lock that isn't held will result in a
      RuntimeError.
      """
      self._multistore._unlock()

    def locked_get(self):
      """Retrieve credential.

      The Storage lock must be held when this is called.

      Returns:
        oauth2client.client.Credentials
      """
      credential = self._multistore._get_credential(self._key)
      if credential:
        credential.set_store(self)
      return credential

    def locked_put(self, credentials):
      """Write a credential.

      The Storage lock must be held when this is called.

      Args:
        credentials: Credentials, the credentials to store.
      """
      self._multistore._update_credential(self._key, credentials)

    def locked_delete(self):
      """Delete a credential.

      The Storage lock must be held when this is called.

      Args:
        credentials: Credentials, the credentials to store.
      """
      self._multistore._delete_credential(self._key)

  def _create_file_if_needed(self):
    """Create an empty file if necessary.

    This method will not initialize the file. Instead it implements a
    simple version of "touch" to ensure the file has been created.
    """
    if not os.path.exists(self._file.filename()):
      old_umask = os.umask(0o177)
      try:
        open(self._file.filename(), 'a+b').close()
      finally:
        os.umask(old_umask)

  def _lock(self):
    """Lock the entire multistore."""
    self._thread_lock.acquire()
    try:
      self._file.open_and_lock()
    except IOError as e:
      if e.errno == errno.ENOSYS:
        logger.warn('File system does not support locking the credentials '
                    'file.')
      elif e.errno ==  errno.ENOLCK:
        logger.warn('File system is out of resources for writing the '
                    'credentials file (is your disk full?).')
      else:
        raise
    if not self._file.is_locked():
      self._read_only = True
      if self._warn_on_readonly:
        logger.warn('The credentials file (%s) is not writable. Opening in '
                    'read-only mode. Any refreshed credentials will only be '
                    'valid for this run.', self._file.filename())
    if os.path.getsize(self._file.filename()) == 0:
      logger.debug('Initializing empty multistore file')
      # The multistore is empty so write out an empty file.
      self._data = {}
      self._write()
    elif not self._read_only or self._data is None:
      # Only refresh the data if we are read/write or we haven't
      # cached the data yet. If we are readonly, we assume is isn't
      # changing out from under us and that we only have to read it
      # once. This prevents us from whacking any new access keys that
      # we have cached in memory but were unable to write out.
      self._refresh_data_cache()

  def _unlock(self):
    """Release the lock on the multistore."""
    self._file.unlock_and_close()
    self._thread_lock.release()

  def _locked_json_read(self):
    """Get the raw content of the multistore file.

    The multistore must be locked when this is called.

    Returns:
      The contents of the multistore decoded as JSON.
    """
    assert self._thread_lock.locked()
    self._file.file_handle().seek(0)
    return json.load(self._file.file_handle())

  def _locked_json_write(self, data):
    """Write a JSON serializable data structure to the multistore.

    The multistore must be locked when this is called.

    Args:
      data: The data to be serialized and written.
    """
    assert self._thread_lock.locked()
    if self._read_only:
      return
    self._file.file_handle().seek(0)
    json.dump(data, self._file.file_handle(), sort_keys=True, indent=2, separators=(',', ': '))
    self._file.file_handle().truncate()

  def _refresh_data_cache(self):
    """Refresh the contents of the multistore.

    The multistore must be locked when this is called.

    Raises:
      NewerCredentialStoreError: Raised when a newer client has written the
        store.
    """
    self._data = {}
    try:
      raw_data = self._locked_json_read()
    except Exception:
      logger.warn('Credential data store could not be loaded. '
                  'Will ignore and overwrite.')
      return

    version = 0
    try:
      version = raw_data['file_version']
    except Exception:
      logger.warn('Missing version for credential data store. It may be '
                  'corrupt or an old version. Overwriting.')
    if version > 1:
      raise NewerCredentialStoreError(
          'Credential file has file_version of %d. '
          'Only file_version of 1 is supported.' % version)

    credentials = []
    try:
      credentials = raw_data['data']
    except (TypeError, KeyError):
      pass

    for cred_entry in credentials:
      try:
        (key, credential) = self._decode_credential_from_json(cred_entry)
        self._data[key] = credential
      except:
        # If something goes wrong loading a credential, just ignore it
        logger.info('Error decoding credential, skipping', exc_info=True)

  def _decode_credential_from_json(self, cred_entry):
    """Load a credential from our JSON serialization.

    Args:
      cred_entry: A dict entry from the data member of our format

    Returns:
      (key, cred) where the key is the key tuple and the cred is the
        OAuth2Credential object.
    """
    raw_key = cred_entry['key']
    key = util.dict_to_tuple_key(raw_key)
    credential = None
    credential = Credentials.new_from_json(json.dumps(cred_entry['credential']))
    return (key, credential)

  def _write(self):
    """Write the cached data back out.

    The multistore must be locked.
    """
    raw_data = {'file_version': 1}
    raw_creds = []
    raw_data['data'] = raw_creds
    for (cred_key, cred) in self._data.items():
      raw_key = dict(cred_key)
      raw_cred = json.loads(cred.to_json())
      raw_creds.append({'key': raw_key, 'credential': raw_cred})
    self._locked_json_write(raw_data)

  def _get_all_credential_keys(self):
    """Gets all the registered credential keys in the multistore.

    Returns:
      A list of dictionaries corresponding to all the keys currently registered
    """
    return [dict(key) for key in self._data.keys()]

  def _get_credential(self, key):
    """Get a credential from the multistore.

    The multistore must be locked.

    Args:
      key: The key used to retrieve the credential

    Returns:
      The credential specified or None if not present
    """
    return self._data.get(key, None)

  def _update_credential(self, key, cred):
    """Update a credential and write the multistore.

    This must be called when the multistore is locked.

    Args:
      key: The key used to retrieve the credential
      cred: The OAuth2Credential to update/set
    """
    self._data[key] = cred
    self._write()

  def _delete_credential(self, key):
    """Delete a credential and write the multistore.

    This must be called when the multistore is locked.

    Args:
      key: The key used to retrieve the credential
    """
    try:
      del self._data[key]
    except KeyError:
      pass
    self._write()

  def _get_storage(self, key):
    """Get a Storage object to get/set a credential.

    This Storage is a 'view' into the multistore.

    Args:
      key: The key used to retrieve the credential

    Returns:
      A Storage object that can be used to get/set this cred
    """
    return self._Storage(self, key)