# 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 pw_cli.envparse."""

import math
import unittest

from pw_cli import envparse

# pylint: disable=no-member


class ErrorError(Exception):
    pass


def error(value: str):
    raise ErrorError('error!')


class TestEnvironmentParser(unittest.TestCase):
    """Tests for envparse.EnvironmentParser."""
    def setUp(self):
        self.raw_env = {
            'PATH': '/bin:/usr/bin:/usr/local/bin',
            'FOO': '2020',
            'ReVeRsE': 'pigweed',
        }

        self.parser = envparse.EnvironmentParser(error_on_unrecognized=True)
        self.parser.add_var('PATH')
        self.parser.add_var('FOO', type=int)
        self.parser.add_var('BAR', type=bool)
        self.parser.add_var('BAZ', type=float, default=math.pi)
        self.parser.add_var('ReVeRsE', type=lambda s: s[::-1])
        self.parser.add_var('INT', type=int)
        self.parser.add_var('ERROR', type=error)

    def test_string_value(self):
        env = self.parser.parse_env(env=self.raw_env)
        self.assertEqual(env.PATH, self.raw_env['PATH'])

    def test_int_value(self):
        env = self.parser.parse_env(env=self.raw_env)
        self.assertEqual(env.FOO, 2020)

    def test_custom_value(self):
        env = self.parser.parse_env(env=self.raw_env)
        self.assertEqual(env.ReVeRsE, 'deewgip')

    def test_empty_value(self):
        env = self.parser.parse_env(env=self.raw_env)
        self.assertEqual(env.BAR, None)

    def test_default_value(self):
        env = self.parser.parse_env(env=self.raw_env)
        self.assertEqual(env.BAZ, math.pi)

    def test_unknown_key(self):
        env = self.parser.parse_env(env=self.raw_env)
        with self.assertRaises(AttributeError):
            env.BBBBB  # pylint: disable=pointless-statement

    def test_bad_value(self):
        raw_env = {**self.raw_env, 'INT': 'not an int'}
        with self.assertRaises(envparse.EnvironmentValueError) as ctx:
            self.parser.parse_env(env=raw_env)

        self.assertEqual(ctx.exception.variable, 'INT')
        self.assertIsInstance(ctx.exception.__cause__, ValueError)

    def test_custom_exception(self):
        raw_env = {**self.raw_env, 'ERROR': 'error'}
        with self.assertRaises(envparse.EnvironmentValueError) as ctx:
            self.parser.parse_env(env=raw_env)

        self.assertEqual(ctx.exception.variable, 'ERROR')
        self.assertIsInstance(ctx.exception.__cause__, ErrorError)


class TestEnvironmentParserWithPrefix(unittest.TestCase):
    """Tests for envparse.EnvironmentParser using a prefix."""
    def setUp(self):
        self.raw_env = {
            'PW_FOO': '001',
            'PW_BAR': '010',
            'PW_BAZ': '100',
            'IGNORED': '011',
        }

    def test_parse_unrecognized_variable(self):
        parser = envparse.EnvironmentParser(prefix='PW_',
                                            error_on_unrecognized=True)
        parser.add_var('PW_FOO')
        parser.add_var('PW_BAR')

        with self.assertRaises(ValueError):
            parser.parse_env(env=self.raw_env)

    def test_parse_unrecognized_but_allowed_suffix(self):
        parser = envparse.EnvironmentParser(prefix='PW_',
                                            error_on_unrecognized=True)
        parser.add_allowed_suffix('_ALLOWED_SUFFIX')

        env = parser.parse_env(env={'PW_FOO_ALLOWED_SUFFIX': '001'})
        self.assertEqual(env.PW_FOO_ALLOWED_SUFFIX, '001')

    def test_parse_allowed_suffix_but_not_suffix(self):
        parser = envparse.EnvironmentParser(prefix='PW_',
                                            error_on_unrecognized=True)
        parser.add_allowed_suffix('_ALLOWED_SUFFIX')

        with self.assertRaises(ValueError):
            parser.parse_env(env={'PW_FOO_ALLOWED_SUFFIX_FOO': '001'})

    def test_parse_ignore_unrecognized(self):
        parser = envparse.EnvironmentParser(prefix='PW_',
                                            error_on_unrecognized=False)
        parser.add_var('PW_FOO')
        parser.add_var('PW_BAR')

        env = parser.parse_env(env=self.raw_env)
        self.assertEqual(env.PW_FOO, self.raw_env['PW_FOO'])
        self.assertEqual(env.PW_BAR, self.raw_env['PW_BAR'])

    def test_add_var_without_prefix(self):
        parser = envparse.EnvironmentParser(prefix='PW_',
                                            error_on_unrecognized=True)
        with self.assertRaises(ValueError):
            parser.add_var('FOO')


class TestStrictBool(unittest.TestCase):
    """Tests for envparse.strict_bool."""
    def setUp(self):
        self.good_bools = ['true', '1', 'TRUE', 'tRuE']
        self.bad_bools = [
            '', 'false', '0', 'foo', '2', '999', 'ok', 'yes', 'no'
        ]

    def test_good_bools(self):
        self.assertTrue(
            all(envparse.strict_bool(val) for val in self.good_bools))

    def test_bad_bools(self):
        self.assertFalse(
            any(envparse.strict_bool(val) for val in self.bad_bools))


if __name__ == '__main__':
    unittest.main()
