"""API authentication."""

import contextlib
import logging
import os
import os.path
import tempfile

import requests

from . import common

TOKEN_FILE_PATH = os.path.join(tempfile.gettempdir(), "tank_utility_token.txt")
"""Name of the file to store a cached token within."""


@contextlib.contextmanager
def umask(context_umask):
    """Modify umask within a context."""
    original_umask = os.umask(context_umask)
    try:
        yield
    finally:
        os.umask(original_umask)


def _get_cached_token():
    """Get a cached API token from a temporary file.

    :rtype: :py:class:`str`
    :returns: API token or empty string

    """
    token = ""
    try:
        with open(TOKEN_FILE_PATH, "r") as f:
            token = f.read()
    except FileNotFoundError:
        logging.info("No existing file %s", TOKEN_FILE_PATH)
    return token


def _cache_token(token):
    """Cache ``token`` in a temporary file.

    :param str token:

    """
    try:
        os.remove(TOKEN_FILE_PATH)
    except FileNotFoundError:
        logging.info("No existing file %s", TOKEN_FILE_PATH)
    with umask(0o077):
        with open(TOKEN_FILE_PATH, "w") as f:
            f.write(token)
        logging.info("Cached token in %s", TOKEN_FILE_PATH)


def get_token(username, password, force=False):
    """Get an API token.

    Unfortunately, the Tank Utility API only offers basic authentication and expires each API token after 24 hours.

    :param str username:
    :param str password:
    :param bool force: (optional) Get a new token even if one is currently cached
    :rtype: :py:class:`str`
    :returns: An API token
    :raises requests.exceptions.HTTPError:

    """
    token = None if force else _get_cached_token()
    if not token:
        response = requests.get(
            common.get_api_url(path="getToken"), auth=requests.auth.HTTPBasicAuth(username, password)
        )
        response.raise_for_status()
        token = response.json()["token"]
        _cache_token(token)
    return token
