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

import logging
import os
import subprocess


LOG = logging.getLogger(__name__)


from subprocess import CalledProcessError  # noqa


def _multi_line_log(level, msg):
    for line in msg.splitlines():
        LOG.log(level, line)


def check_call(*popenargs, timeout=None, **kwargs):
    # A variation of subprocess.check_call that captures and then
    # logs the output of the command which makes it easier for tests
    # to capture it.

    kwargs['stdout'] = subprocess.PIPE
    kwargs['stderr'] = subprocess.STDOUT

    cmd = kwargs.get("args")
    if cmd is None:
        cmd = popenargs[0]
    if 'cwd' in kwargs:
        LOG.debug('cwd = {}'.format(kwargs['cwd']))
    LOG.debug('$ {}'.format(' '.join(cmd)))

    # Copy full environment to pass in so we can include any of our own
    # environment variables with it.
    env = os.environ.copy()
    env_extras = kwargs.pop('env', None)
    if env_extras:
        env.update(env_extras)

    completed = subprocess.run(*popenargs, env=env, **kwargs)
    _multi_line_log(logging.DEBUG, completed.stdout.decode('utf-8'))

    if completed.returncode:
        raise subprocess.CalledProcessError(completed.returncode, cmd)
    return 0


def check_output(*popenargs, timeout=None, **kwargs):
    # A variation of subprocess.check_output that captures stderr and
    # logs it instead of letting it go to the console directly to make
    # it easier for tests to capture it.

    # NOTE(dhellmann): copied from subprocess.py vv
    if 'stdout' in kwargs:
        raise ValueError('stdout argument not allowed, it will be overridden.')
    if 'input' in kwargs and kwargs['input'] is None:
        # Explicitly passing input=None was previously equivalent to passing an
        # empty string. That is maintained here for backwards compatibility.
        kwargs['input'] = '' if kwargs.get('universal_newlines', False) else b''
    # NOTE(dhellmann): end copied from subprocess.py ^^

    cmd = kwargs.get("args")
    if cmd is None:
        cmd = popenargs[0]
    if 'cwd' in kwargs:
        LOG.debug('cwd = {}'.format(kwargs['cwd']))
    LOG.debug('$ {}'.format(' '.join(cmd)))

    if 'stderr' not in kwargs:
        kwargs['stderr'] = subprocess.PIPE

    # Copy full environment to pass in so we can include any of our own
    # environment variables with it.
    env = os.environ.copy()
    env_extras = kwargs.pop('env', None)
    if env_extras:
        env.update(env_extras)

    completed = subprocess.run(*popenargs,
                               stdout=subprocess.PIPE,
                               timeout=timeout,
                               check=True,
                               env=env,
                               **kwargs)

    if completed.stderr:
        _multi_line_log(logging.WARNING, completed.stderr.decode('utf-8'))

    return completed.stdout