#!/usr/bin/python2

import collections
import os
import mox
import types
import unittest

import common
from autotest_lib.client.common_lib import autotemp
from autotest_lib.client.common_lib import global_config
from autotest_lib.client.common_lib import lsbrelease_utils


global_config_ini_contents = """
[SECTION_A]
value_1: 6.0
value_2: hello
value_3: true
value_4: FALSE
value_5: tRuE
value_6: falsE

[SECTION_B]
value_1: -5
value_2: 2.3
value_3: 0
value_4: 7

[SECTION_C]
value_1: nobody@localhost

[SECTION_D]
value_1: 1

[SECTION_E]
value_1: 1
value_2: 2
value_a: A
random: 1
wireless_ssid_1.2.3.4/24: ssid_1
wireless_ssid_4.3.2.1/16: ssid_2
"""

moblab_config_ini_contents = """
[SECTION_C]
value_1: moblab@remotehost

[SECTION_D]
value_1: 2
"""

shadow_config_ini_contents = """
[SECTION_C]
value_1: somebody@remotehost
"""


def create_config_files():
    """Create config files to be used for test."""
    global_temp = autotemp.tempfile("global", ".ini", text=True)
    os.write(global_temp.fd, global_config_ini_contents)

    moblab_temp = autotemp.tempfile("moblab", ".ini", text=True)
    os.write(moblab_temp.fd, moblab_config_ini_contents)

    shadow_temp = autotemp.tempfile("shadow", ".ini", text=True)
    os.write(shadow_temp.fd, shadow_config_ini_contents)

    return (global_temp, shadow_temp, moblab_temp)


class global_config_test(mox.MoxTestBase):
    """Test class"""
    # grab the singelton
    conf = global_config.global_config

    def setUp(self):
        """Setup config files for test."""
        super(global_config_test, self).setUp()
        # set the config files to our test files
        (self.global_temp, self.shadow_temp,
                self.moblab_temp) = create_config_files()

        self.conf.set_config_files(self.global_temp.name, self.shadow_temp.name,
                                   self.moblab_temp.name)


    def tearDown(self):
        """Cleanup and reset config settings."""
        self.shadow_temp.clean()
        self.moblab_temp.clean()
        self.global_temp.clean()
        self.conf.set_config_files(global_config.DEFAULT_CONFIG_FILE,
                                   global_config.DEFAULT_SHADOW_FILE,
                                   global_config.DEFAULT_MOBLAB_FILE)


    def test_float(self):
        """Test converting float value."""
        val = self.conf.get_config_value("SECTION_A", "value_1", float)
        self.assertEquals(type(val), types.FloatType)
        self.assertEquals(val, 6.0)


    def test_int(self):
        """Test converting int value."""
        val = self.conf.get_config_value("SECTION_B", "value_1", int)
        self.assertEquals(type(val), types.IntType)
        self.assertTrue(val < 0)
        val = self.conf.get_config_value("SECTION_B", "value_3", int)
        self.assertEquals(val, 0)
        val = self.conf.get_config_value("SECTION_B", "value_4", int)
        self.assertTrue(val > 0)


    def test_string(self):
        """Test converting string value."""
        val = self.conf.get_config_value("SECTION_A", "value_2")
        self.assertEquals(type(val),types.StringType)
        self.assertEquals(val, "hello")


    def setIsMoblab(self, is_moblab):
        """Set lsbrelease_utils.is_moblab result.

        @param is_moblab: Value to have lsbrelease_utils.is_moblab to return.
        """
        self.mox.StubOutWithMock(lsbrelease_utils, 'is_moblab')
        lsbrelease_utils.is_moblab().AndReturn(is_moblab)


    def test_override_non_moblab(self):
        """Test value overriding works in non-moblab setup."""
        self.setIsMoblab(False)
        self.mox.ReplayAll()

        self.conf.reset_config_values()

        # Confirm shadow config overrides global config.
        val = self.conf.get_config_value("SECTION_C", "value_1")
        self.assertEquals(val, "somebody@remotehost")

        # Confirm moblab config should be ignored in non-moblab environment..
        val = self.conf.get_config_value("SECTION_D", "value_1")
        self.assertEquals(val, "1")


    def test_override_moblab(self):
        """Test value overriding works in moblab setup."""
        self.setIsMoblab(True)
        self.mox.ReplayAll()

        self.conf.reset_config_values()

        # Confirm shadow config overrides both moblab and global config.
        val = self.conf.get_config_value("SECTION_C", "value_1")
        self.assertEquals(val, "somebody@remotehost")

        # Confirm moblab config should override global config in moblab.
        val = self.conf.get_config_value("SECTION_D", "value_1")
        self.assertEquals(val, "2")


    def test_exception(self):
        """Test exception to be raised on invalid config value."""
        error = 0
        try:
            val = self.conf.get_config_value("SECTION_B", "value_2", int)
        except:
            error = 1
        self.assertEquals(error, 1)


    def test_boolean(self):
        """Test converting boolean value."""
        val = self.conf.get_config_value("SECTION_A", "value_3", bool)
        self.assertEquals(val, True)
        val = self.conf.get_config_value("SECTION_A", "value_4", bool)
        self.assertEquals(val, False)
        val = self.conf.get_config_value("SECTION_A", "value_5", bool)
        self.assertEquals(val, True)
        val = self.conf.get_config_value("SECTION_A", "value_6", bool)
        self.assertEquals(val, False)


    def test_defaults(self):
        """Test default value works."""
        val = self.conf.get_config_value("MISSING", "foo", float, 3.6)
        self.assertEquals(val, 3.6)
        val = self.conf.get_config_value("SECTION_A", "novalue", str, "default")
        self.assertEquals(val, "default")


    def test_fallback_key(self):
        """Test fallback value works."""
        val = self.conf.get_config_value_with_fallback(
                "SECTION_A", "value_3", "value_4", bool)
        self.assertEquals(val, True)

        val = self.conf.get_config_value_with_fallback(
                "SECTION_A", "not_existing", "value_4", bool)
        self.assertEquals(val, False)

        val = self.conf.get_config_value_with_fallback(
                "SECTION_A", "not_existing", "value_4",
                fallback_section='SECTION_B')
        self.assertEquals(val, '7')

        self.assertRaises(
                Exception, self.conf.get_config_value_with_fallback,
                "SECTION_A", "not_existing", "also_not_existing", bool)


    def test_get_config_value_regex(self):
        """Test get_config_value_regex works."""
        configs = self.conf.get_config_value_regex('SECTION_E', 'value_\d+',
                                                   int)
        self.assertEquals(configs, {'value_1': 1, 'value_2': 2})
        configs = self.conf.get_config_value_regex('SECTION_E', 'value_.*')
        self.assertEquals(configs, {'value_1': '1', 'value_2': '2',
                                    'value_a': 'A'})
        configs = self.conf.get_config_value_regex('SECTION_E',
                                                   'wireless_ssid_.*')
        self.assertEquals(configs, {'wireless_ssid_1.2.3.4/24': 'ssid_1',
                                    'wireless_ssid_4.3.2.1/16': 'ssid_2'})


    def test_get_section_as_dict(self):
        """Test get_section_as_dict."""
        got = self.conf.get_section_as_dict('SECTION_D')
        self.assertEqual(got, collections.OrderedDict([('value_1', '1')]))


    def test_get_section_as_dict_missing(self):
        """Test get_section_as_dict with missing section."""
        got = self.conf.get_section_as_dict('FOOBAR')
        self.assertEqual(got, collections.OrderedDict())


# this is so the test can be run in standalone mode
if __name__ == '__main__':
    """Main"""
    unittest.main()
