# Copyright (C) 2021 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os
import getpass
import sys

from subprocess import CalledProcessError
from webkitcorepy import OutputCapture, Terminal

_cache = dict()


def credentials(url, required=True, name=None, prompt=None, key_name='password'):
    global _cache

    name = name or url.split('/')[2].replace('.', '_')
    if _cache.get(name):
        return _cache.get(name)

    username = os.environ.get('{}_USERNAME'.format(name.upper()))
    key = os.environ.get('{}_{}'.format(name.upper(), key_name.upper()))

    if username and key:
        _cache[name] = (username, key)
        return username, key

    with OutputCapture():
        try:
            import keyring
        except (CalledProcessError, ImportError):
            keyring = None

    username_prompted = False
    key_prompted = False
    if not username:
        try:
            if keyring:
                username = keyring.get_password(url, 'username')
        except (RuntimeError, AttributeError):
            pass

        if not username and required:
            if not sys.stderr.isatty() or not sys.stdin.isatty():
                raise OSError('No tty to prompt user for username')
            sys.stderr.write("Authentication required to use {}\n".format(prompt or name))
            sys.stderr.write('Username: ')
            username = Terminal.input()
            username_prompted = True

    if not key:
        try:
            if keyring:
                key = keyring.get_password(url, username)
        except (RuntimeError, AttributeError):
            pass

        if not key and required:
            if not sys.stderr.isatty() or not sys.stdin.isatty():
                raise OSError('No tty to prompt user for username')
            key = getpass.getpass('{}: '.format(key_name.capitalize()))
            key_prompted = True

    if username and key:
        _cache[name] = (username, key)

    if keyring and (username_prompted or key_prompted):
        sys.stderr.write('Store username and {} in system keyring for {}? (Y/N): '.format(key_name, url))
        response = Terminal.input()
        if response.lower() in ['y', 'yes', 'ok']:
            sys.stderr.write('Storing credentials...\n')
            keyring.set_password(url, 'username', username)
            keyring.set_password(url, username, key)
        else:
            sys.stderr.write('Credentials cached in process.\n')

    return username, key
