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

"""

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


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

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 can 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?).')
            elif e.errno == errno.EDEADLK:
                logger.warn('Lock contention on multistore file, opening '
                            'in read-only mode.')
            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)
