# Copyright 2020 The Pigweed Authors
#
# 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
#
#     https://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.
"""Tests for env_setup.environment.

This tests the error-checking, context manager, and written environment scripts
of the Environment class.

Tests that end in "_ctx" modify the environment and validate it in-process.

Tests that end in "_written" write the environment to a file intended to be
evaluated by the shell, then launches the shell and then saves the environment.
This environment is then validated in the test process.
"""

import logging
import os
import subprocess
import tempfile
import unittest

# TODO(mohrr) remove import-error disabling, not sure why pylint has issues
# with it.
import environment  # pylint: disable=import-error


class WrittenEnvFailure(Exception):
    pass


def _evaluate_env_in_shell(env):
    """Write env to a file then evaluate and save the resulting environment.

    Write env to a file, then launch a shell command that sources that file
    and dumps the environment to stdout. Parse that output into a dict and
    return it.

    Args:
      env(environment.Environment): environment to write out

    Returns dictionary of resulting environment.
    """

    # Write env sourcing script to file.
    with tempfile.NamedTemporaryFile(
            prefix='pw-test-written-env-',
            suffix='.bat' if os.name == 'nt' else '.sh',
            delete=False,
            mode='w+') as temp:
        env.write(temp)
        temp_name = temp.name

    # Evaluate env sourcing script and capture output of 'env'.
    if os.name == 'nt':
        # On Windows you just run batch files and they modify your
        # environment, no need to call 'source' or '.'.
        cmd = '{} && env'.format(temp_name)
    else:
        # Using '.' instead of 'source' because 'source' is not POSIX.
        cmd = '. {} && env'.format(temp_name)

    res = subprocess.run(cmd, capture_output=True, shell=True)
    if res.returncode:
        raise WrittenEnvFailure(res.stderr)

    # Parse environment from stdout of subprocess.
    env_ret = {}
    for line in res.stdout.splitlines():
        line = line.decode()

        # Some people inexplicably have newlines in some of their
        # environment variables. This module does not allow that so we can
        # ignore any such extra lines.
        if '=' not in line:
            continue

        var, value = line.split('=', 1)
        env_ret[var] = value

    return env_ret


class EnvironmentTest(unittest.TestCase):
    """Tests for env_setup.environment."""
    def setUp(self):
        self.env = environment.Environment()

        self.var_already_set = 'var_already_set'
        os.environ[self.var_already_set] = 'orig value'
        self.assertIn(self.var_already_set, os.environ)

        self.var_not_set = 'var_not_set'
        if self.var_not_set in os.environ:
            del os.environ[self.var_not_set]
        self.assertNotIn(self.var_not_set, os.environ)

        self.orig_env = os.environ.copy()

    def tearDown(self):
        self.assertEqual(os.environ, self.orig_env)

    def test_set_notpresent_ctx(self):
        self.env.set(self.var_not_set, '1')
        with self.env(export=False) as env:
            self.assertIn(self.var_not_set, env)
            self.assertEqual(env[self.var_not_set], '1')

    def test_set_notpresent_written(self):
        self.env.set(self.var_not_set, '1')
        env = _evaluate_env_in_shell(self.env)
        self.assertIn(self.var_not_set, env)
        self.assertEqual(env[self.var_not_set], '1')

    def test_set_present_ctx(self):
        self.env.set(self.var_already_set, '1')
        with self.env(export=False) as env:
            self.assertIn(self.var_already_set, env)
            self.assertEqual(env[self.var_already_set], '1')

    def test_set_present_written(self):
        self.env.set(self.var_already_set, '1')
        env = _evaluate_env_in_shell(self.env)
        self.assertIn(self.var_already_set, env)
        self.assertEqual(env[self.var_already_set], '1')

    def test_clear_notpresent_ctx(self):
        self.env.clear(self.var_not_set)
        with self.env(export=False) as env:
            self.assertNotIn(self.var_not_set, env)

    def test_clear_notpresent_written(self):
        self.env.clear(self.var_not_set)
        env = _evaluate_env_in_shell(self.env)
        self.assertNotIn(self.var_not_set, env)

    def test_clear_present_ctx(self):
        self.env.clear(self.var_already_set)
        with self.env(export=False) as env:
            self.assertNotIn(self.var_already_set, env)

    def test_clear_present_written(self):
        self.env.clear(self.var_already_set)
        env = _evaluate_env_in_shell(self.env)
        self.assertNotIn(self.var_already_set, env)

    def test_nonglobal(self):
        self.env.set(self.var_not_set, '1')
        with self.env(export=False) as env:
            self.assertIn(self.var_not_set, env)
            self.assertNotIn(self.var_not_set, os.environ)

    def test_global(self):
        self.env.set(self.var_not_set, '1')
        with self.env(export=True) as env:
            self.assertIn(self.var_not_set, env)
            self.assertIn(self.var_not_set, os.environ)

    def test_set_badnametype(self):
        with self.assertRaises(environment.BadNameType):
            self.env.set(123, '123')

    def test_set_badvaluetype(self):
        with self.assertRaises(environment.BadValueType):
            self.env.set('var', 123)

    def test_prepend_badnametype(self):
        with self.assertRaises(environment.BadNameType):
            self.env.prepend(123, '123')

    def test_prepend_badvaluetype(self):
        with self.assertRaises(environment.BadValueType):
            self.env.prepend('var', 123)

    def test_append_badnametype(self):
        with self.assertRaises(environment.BadNameType):
            self.env.append(123, '123')

    def test_append_badvaluetype(self):
        with self.assertRaises(environment.BadValueType):
            self.env.append('var', 123)

    def test_set_badname_empty(self):
        with self.assertRaises(environment.BadVariableName):
            self.env.set('', '123')

    def test_set_badname_digitstart(self):
        with self.assertRaises(environment.BadVariableName):
            self.env.set('123', '123')

    def test_set_badname_equals(self):
        with self.assertRaises(environment.BadVariableName):
            self.env.set('foo=bar', '123')

    def test_set_badname_period(self):
        with self.assertRaises(environment.BadVariableName):
            self.env.set('abc.def', '123')

    def test_set_badname_hyphen(self):
        with self.assertRaises(environment.BadVariableName):
            self.env.set('abc-def', '123')

    def test_set_empty_value(self):
        with self.assertRaises(environment.EmptyValue):
            self.env.set('var', '')

    def test_set_newline_in_value(self):
        with self.assertRaises(environment.NewlineInValue):
            self.env.set('var', '123\n456')


class _PrependAppendEnvironmentTest(unittest.TestCase):
    """Tests for env_setup.environment."""
    def __init__(self, *args, **kwargs):
        windows = kwargs.pop('windows', False)
        pathsep = kwargs.pop('pathsep', os.pathsep)
        super(_PrependAppendEnvironmentTest, self).__init__(*args, **kwargs)
        self.windows = windows
        self.pathsep = pathsep

        # If we're testing Windows behavior and actually running on Windows,
        # actually launch a subprocess to evaluate the shell init script.
        # Likewise if we're testing POSIX behavior and actually on a POSIX
        # system. Tests can check self.run_shell_tests and exit without
        # doing anything.
        real_windows = (os.name == 'nt')
        self.run_shell_tests = (self.windows == real_windows)

    def setUp(self):
        self.env = environment.Environment(windows=self.windows,
                                           pathsep=self.pathsep)

        self.var_already_set = 'var_already_set'
        os.environ[self.var_already_set] = self.pathsep.join(
            'one two three'.split())
        self.assertIn(self.var_already_set, os.environ)

        self.var_not_set = 'var_not_set'
        if self.var_not_set in os.environ:
            del os.environ[self.var_not_set]
        self.assertNotIn(self.var_not_set, os.environ)

        self.orig_env = os.environ.copy()

    def split(self, val):
        return val.split(self.pathsep)

    def tearDown(self):
        self.assertEqual(os.environ, self.orig_env)


# TODO(mohrr) remove disable=useless-object-inheritance once in Python 3.
# pylint: disable=useless-object-inheritance
class _AppendPrependTestMixin(object):
    def test_prepend_present_ctx(self):
        orig = os.environ[self.var_already_set]
        self.env.prepend(self.var_already_set, 'path')
        with self.env(export=False) as env:
            self.assertEqual(env[self.var_already_set],
                             self.pathsep.join(('path', orig)))

    def test_prepend_present_written(self):
        if not self.run_shell_tests:
            return

        orig = os.environ[self.var_already_set]
        self.env.prepend(self.var_already_set, 'path')
        env = _evaluate_env_in_shell(self.env)
        self.assertEqual(env[self.var_already_set],
                         self.pathsep.join(('path', orig)))

    def test_prepend_notpresent_ctx(self):
        self.env.prepend(self.var_not_set, 'path')
        with self.env(export=False) as env:
            self.assertEqual(env[self.var_not_set], 'path')

    def test_prepend_notpresent_written(self):
        if not self.run_shell_tests:
            return

        self.env.prepend(self.var_not_set, 'path')
        env = _evaluate_env_in_shell(self.env)
        self.assertEqual(env[self.var_not_set], 'path')

    def test_append_present_ctx(self):
        orig = os.environ[self.var_already_set]
        self.env.append(self.var_already_set, 'path')
        with self.env(export=False) as env:
            self.assertEqual(env[self.var_already_set],
                             self.pathsep.join((orig, 'path')))

    def test_append_present_written(self):
        if not self.run_shell_tests:
            return

        orig = os.environ[self.var_already_set]
        self.env.append(self.var_already_set, 'path')
        env = _evaluate_env_in_shell(self.env)
        self.assertEqual(env[self.var_already_set],
                         self.pathsep.join((orig, 'path')))

    def test_append_notpresent_ctx(self):
        self.env.append(self.var_not_set, 'path')
        with self.env(export=False) as env:
            self.assertEqual(env[self.var_not_set], 'path')

    def test_append_notpresent_written(self):
        if not self.run_shell_tests:
            return

        self.env.append(self.var_not_set, 'path')
        env = _evaluate_env_in_shell(self.env)
        self.assertEqual(env[self.var_not_set], 'path')


class WindowsEnvironmentTest(_PrependAppendEnvironmentTest,
                             _AppendPrependTestMixin):
    def __init__(self, *args, **kwargs):
        kwargs['pathsep'] = ';'
        kwargs['windows'] = True
        super(WindowsEnvironmentTest, self).__init__(*args, **kwargs)


class PosixEnvironmentTest(_PrependAppendEnvironmentTest,
                           _AppendPrependTestMixin):
    def __init__(self, *args, **kwargs):
        kwargs['pathsep'] = ':'
        kwargs['windows'] = False
        super(PosixEnvironmentTest, self).__init__(*args, **kwargs)
        self.real_windows = (os.name == 'nt')


if __name__ == '__main__':
    import sys
    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
    unittest.main()
