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

"""Utilities for reading OAuth 2.0 client secret files.

A client_secrets.json file contains all the information needed to interact with
an OAuth 2.0 protected service.
"""

import json
from chromite.third_party import six


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

# Properties that make a client_secrets.json file valid.
TYPE_WEB = 'web'
TYPE_INSTALLED = 'installed'

VALID_CLIENT = {
    TYPE_WEB: {
        'required': [
            'client_id',
            'client_secret',
            'redirect_uris',
            'auth_uri',
            'token_uri',
        ],
        'string': [
            'client_id',
            'client_secret',
        ],
    },
    TYPE_INSTALLED: {
        'required': [
            'client_id',
            'client_secret',
            'redirect_uris',
            'auth_uri',
            'token_uri',
        ],
        'string': [
            'client_id',
            'client_secret',
        ],
    },
}


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


class InvalidClientSecretsError(Error):
    """Format of ClientSecrets file is invalid."""


def _validate_clientsecrets(clientsecrets_dict):
    """Validate parsed client secrets from a file.

    Args:
        clientsecrets_dict: dict, a dictionary holding the client secrets.

    Returns:
        tuple, a string of the client type and the information parsed
        from the file.
    """
    _INVALID_FILE_FORMAT_MSG = (
        'Invalid file format. See '
        'https://developers.google.com/api-client-library/'
        'python/guide/aaa_client_secrets')

    if clientsecrets_dict is None:
        raise InvalidClientSecretsError(_INVALID_FILE_FORMAT_MSG)
    try:
        (client_type, client_info), = clientsecrets_dict.items()
    except (ValueError, AttributeError):
        raise InvalidClientSecretsError(
            _INVALID_FILE_FORMAT_MSG + ' '
            'Expected a JSON object with a single property for a "web" or '
            '"installed" application')

    if client_type not in VALID_CLIENT:
        raise InvalidClientSecretsError(
            'Unknown client type: %s.' % (client_type,))

    for prop_name in VALID_CLIENT[client_type]['required']:
        if prop_name not in client_info:
            raise InvalidClientSecretsError(
                'Missing property "%s" in a client type of "%s".' %
                (prop_name, client_type))
    for prop_name in VALID_CLIENT[client_type]['string']:
        if client_info[prop_name].startswith('[['):
            raise InvalidClientSecretsError(
                'Property "%s" is not configured.' % prop_name)
    return client_type, client_info


def load(fp):
    obj = json.load(fp)
    return _validate_clientsecrets(obj)


def loads(s):
    obj = json.loads(s)
    return _validate_clientsecrets(obj)


def _loadfile(filename):
    try:
        with open(filename, 'r') as fp:
            obj = json.load(fp)
    except IOError:
        raise InvalidClientSecretsError('File not found: "%s"' % filename)
    return _validate_clientsecrets(obj)


def loadfile(filename, cache=None):
    """Loading of client_secrets JSON file, optionally backed by a cache.

    Typical cache storage would be App Engine memcache service,
    but you can pass in any other cache client that implements
    these methods:

    * ``get(key, namespace=ns)``
    * ``set(key, value, namespace=ns)``

    Usage::

        # without caching
        client_type, client_info = loadfile('secrets.json')
        # using App Engine memcache service
        from google.appengine.api import memcache
        client_type, client_info = loadfile('secrets.json', cache=memcache)

    Args:
        filename: string, Path to a client_secrets.json file on a filesystem.
        cache: An optional cache service client that implements get() and set()
        methods. If not specified, the file is always being loaded from
                 a filesystem.

    Raises:
        InvalidClientSecretsError: In case of a validation error or some
                                   I/O failure. Can happen only on cache miss.

    Returns:
        (client_type, client_info) tuple, as _loadfile() normally would.
        JSON contents is validated only during first load. Cache hits are not
        validated.
    """
    _SECRET_NAMESPACE = 'oauth2client:secrets#ns'

    if not cache:
        return _loadfile(filename)

    obj = cache.get(filename, namespace=_SECRET_NAMESPACE)
    if obj is None:
        client_type, client_info = _loadfile(filename)
        obj = {client_type: client_info}
        cache.set(filename, obj, namespace=_SECRET_NAMESPACE)

    return next(six.iteritems(obj))
