import os
import sys
from . import HendrixTestCase, TEST_SETTINGS
from hendrix.contrib import SettingsError
from hendrix.options import options as hx_options
from hendrix import ux
from mock import patch


class TestMain(HendrixTestCase):

    def setUp(self):
        super(TestMain, self).setUp()
        self.DEFAULTS = hx_options()
        os.environ['DJANGO_SETTINGS_MODULE'] = ''
        self.devnull = open(os.devnull, 'w')
        self.args_list = ['hx', 'start']
        self.patcher = patch('hendrix.ux.findSettingsModule')
        self.patcher.start()

    def tearDown(self):
        super(TestMain, self).tearDown()
        self.devnull.close()
        self.patcher.stop()

    def test_settings_from_system_variable(self):
        django_settings = 'django.inanity'
        with patch('hendrix.ux.findSettingsModule') as findSettingsMod:
            findSettingsMod.return_value = django_settings
            options = self.DEFAULTS
            self.assertEqual(options['settings'], '')
            options = ux.djangoVsWsgi(options)
            self.assertEqual(options['settings'], django_settings)

    def test_settings_wsgi_absense(self):
        with patch('hendrix.ux.findSettingsModule') as findSettingsMod:
            findSettingsMod.return_value = ""
            self.assertRaises(SettingsError, ux.djangoVsWsgi, self.DEFAULTS)

    def test_user_settings_overrides_system_variable(self):
        django_settings = 'django.inanity'
        with patch('hendrix.ux.findSettingsModule') as findSettingsMod:
            findSettingsMod.return_value = django_settings
            options = self.DEFAULTS
            user_settings = 'myproject.settings'
            options['settings'] = user_settings
            self.assertEqual(options['settings'], user_settings)
            options = ux.djangoVsWsgi(options)
            self.assertEqual(options['settings'], user_settings)

    def test_wsgi_correct_wsgi_path_works(self):
        wsgi_dot_path = 'hendrix.test.wsgi'
        options = self.DEFAULTS
        options.update({'wsgi': wsgi_dot_path})
        options = ux.djangoVsWsgi(options)
        self.assertEqual(options['wsgi'], wsgi_dot_path)

    def test_wsgi_wrong_path_raises(self):
        wsgi_dot_path = '_this.leads.nowhere.man'
        options = self.DEFAULTS
        options.update({'wsgi': wsgi_dot_path})

        self.assertRaises(ImportError, ux.djangoVsWsgi, options)

    def test_cwd_exposure(self):
        cwd = os.getcwd()
        _path = sys.path
        sys.path = [p for p in _path if p != cwd]
        self.assertTrue(cwd not in sys.path)
        ux.exposeProject(self.DEFAULTS)
        self.assertTrue(cwd in sys.path)

    def test_pythonpath(self):
        options = self.DEFAULTS
        test_path = os.path.join(
            os.path.dirname(os.getcwd()),
            'hendrix/test/testproject'
        )
        options['pythonpath'] = test_path
        ux.exposeProject(options)
        self.assertTrue(test_path in sys.path)
        sys.path = [p for p in sys.path if p != test_path]

    def test_shitty_pythonpath(self):
        options = self.DEFAULTS
        test_path = '/if/u/have/this/path/you/suck'
        options['pythonpath'] = test_path
        self.assertRaises(IOError, ux.exposeProject, options)

    def test_dev_friendly_options(self):
        options = self.DEFAULTS
        options['dev'] = True
        self.assertFalse(options['reload'])
        self.assertFalse(options['loud'])
        options = ux.devFriendly(options)
        self.assertTrue(options['reload'])
        self.assertTrue(options['loud'])

    def test_noise_control_daemonize(self):
        options = self.DEFAULTS
        options['quiet'] = True
        options['daemonize'] = True
        stdout = sys.stdout
        stderr = sys.stderr
        redirect = ux.noiseControl(options)
        self.assertEqual(sys.stdout.name, stdout.name)
        self.assertEqual(sys.stderr.name, stderr.name)

        self.assertEqual(redirect, None)

    def test_noise_control_traceback(self):
        options = self.DEFAULTS
        options['quiet'] = True
        options['daemonize'] = True
        options['traceback'] = True
        stdout = sys.stdout
        stderr = sys.stderr
        redirect = ux.noiseControl(options)
        self.assertEqual(sys.stdout.name, stdout.name)
        self.assertEqual(sys.stderr.name, stderr.name)

        self.assertEqual(redirect, None)

    def test_main_with_daemonize(self):
        sys.argv = self.args_list + ['-d', '--settings', TEST_SETTINGS]

        class Process(object):
            def poll(self):
                return 0
        with patch('time.sleep'):
            with patch('subprocess.Popen') as popen:
                popen.return_value = Process()
                ux.main()
                self.assertTrue(popen.called)
                self.assertTrue('--settings' in popen.call_args[0][0])
        sys.argv = []

    def test_options_structure(self):
        """
        A test to ensure that HendrixDeploy.options also has the complete set
        of options available
        """
        deploy = self.wsgiDeploy()
        expected_keys = self.DEFAULTS.keys()
        actual_keys = deploy.options.keys()
        self.assertListEqual(expected_keys, actual_keys)

[((14, 24, 14, 36), 'hendrix.options.options', 'hx_options', ({}, {}), '()', True, 'from hendrix.options import options as hx_options\n'), ((18, 23, 18, 61), 'mock.patch', 'patch', ({(18, 29, 18, 60): '"""hendrix.ux.findSettingsModule"""'}, {}), "('hendrix.ux.findSettingsModule')", False, 'from mock import patch\n'), ((55, 18, 55, 42), 'hendrix.ux.djangoVsWsgi', 'ux.djangoVsWsgi', ({(55, 34, 55, 41): 'options'}, {}), '(options)', False, 'from hendrix import ux\n'), ((66, 14, 66, 25), 'os.getcwd', 'os.getcwd', ({}, {}), '()', False, 'import os\n'), ((70, 8, 70, 39), 'hendrix.ux.exposeProject', 'ux.exposeProject', ({(70, 25, 70, 38): 'self.DEFAULTS'}, {}), '(self.DEFAULTS)', False, 'from hendrix import ux\n'), ((80, 8, 80, 33), 'hendrix.ux.exposeProject', 'ux.exposeProject', ({(80, 25, 80, 32): 'options'}, {}), '(options)', False, 'from hendrix import ux\n'), ((95, 18, 95, 41), 'hendrix.ux.devFriendly', 'ux.devFriendly', ({(95, 33, 95, 40): 'options'}, {}), '(options)', False, 'from hendrix import ux\n'), ((105, 19, 105, 43), 'hendrix.ux.noiseControl', 'ux.noiseControl', ({(105, 35, 105, 42): 'options'}, {}), '(options)', False, 'from hendrix import ux\n'), ((118, 19, 118, 43), 'hendrix.ux.noiseControl', 'ux.noiseControl', ({(118, 35, 118, 42): 'options'}, {}), '(options)', False, 'from hendrix import ux\n'), ((28, 13, 28, 51), 'mock.patch', 'patch', ({(28, 19, 28, 50): '"""hendrix.ux.findSettingsModule"""'}, {}), "('hendrix.ux.findSettingsModule')", False, 'from mock import patch\n'), ((32, 22, 32, 46), 'hendrix.ux.djangoVsWsgi', 'ux.djangoVsWsgi', ({(32, 38, 32, 45): 'options'}, {}), '(options)', False, 'from hendrix import ux\n'), ((36, 13, 36, 51), 'mock.patch', 'patch', ({(36, 19, 36, 50): '"""hendrix.ux.findSettingsModule"""'}, {}), "('hendrix.ux.findSettingsModule')", False, 'from mock import patch\n'), ((42, 13, 42, 51), 'mock.patch', 'patch', ({(42, 19, 42, 50): '"""hendrix.ux.findSettingsModule"""'}, {}), "('hendrix.ux.findSettingsModule')", False, 'from mock import patch\n'), ((48, 22, 48, 46), 'hendrix.ux.djangoVsWsgi', 'ux.djangoVsWsgi', ({(48, 38, 48, 45): 'options'}, {}), '(options)', False, 'from hendrix import ux\n'), ((130, 13, 130, 32), 'mock.patch', 'patch', ({(130, 19, 130, 31): '"""time.sleep"""'}, {}), "('time.sleep')", False, 'from mock import patch\n'), ((76, 28, 76, 39), 'os.getcwd', 'os.getcwd', ({}, {}), '()', False, 'import os\n'), ((131, 17, 131, 42), 'mock.patch', 'patch', ({(131, 23, 131, 41): '"""subprocess.Popen"""'}, {}), "('subprocess.Popen')", False, 'from mock import patch\n'), ((133, 16, 133, 25), 'hendrix.ux.main', 'ux.main', ({}, {}), '()', False, 'from hendrix import ux\n')]