#!/usr/bin/env python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.

import mozfile
import mozhttpd
import os
import shutil
import tempfile
import unittest
from mozprofile.cli import MozProfileCLI
from mozprofile.prefs import Preferences
from mozprofile.profile import Profile

here = os.path.dirname(os.path.abspath(__file__))

class PreferencesTest(unittest.TestCase):
    """test mozprofile preference handling"""

    # preferences from files/prefs_with_comments.js
    _prefs_with_comments = {'browser.startup.homepage': 'http://planet.mozilla.org',
                            'zoom.minPercent': 30,
                            'zoom.maxPercent': 300,
                            'webgl.verbose': 'false'}

    def run_command(self, *args):
        """
        invokes mozprofile command line via the CLI factory
        - args : command line arguments (equivalent of sys.argv[1:])
        """

        # instantiate the factory
        cli = MozProfileCLI(list(args))

        # create the profile
        profile = cli.profile()

        # return path to profile
        return profile.profile

    def compare_generated(self, _prefs, commandline):
        """
        writes out to a new profile with mozprofile command line
        reads the generated preferences with prefs.py
        compares the results
        cleans up
        """
        profile = self.run_command(*commandline)
        prefs_file = os.path.join(profile, 'user.js')
        self.assertTrue(os.path.exists(prefs_file))
        read = Preferences.read_prefs(prefs_file)
        if isinstance(_prefs, dict):
            read = dict(read)
        self.assertEqual(_prefs, read)
        shutil.rmtree(profile)

    def test_basic_prefs(self):
        """test setting a pref from the command line entry point"""

        _prefs = {"browser.startup.homepage": "http://planet.mozilla.org/"}
        commandline = []
        _prefs = _prefs.items()
        for pref, value in _prefs:
            commandline += ["--pref", "%s:%s" % (pref, value)]
        self.compare_generated(_prefs, commandline)

    def test_ordered_prefs(self):
        """ensure the prefs stay in the right order"""
        _prefs = [("browser.startup.homepage", "http://planet.mozilla.org/"),
                  ("zoom.minPercent", 30),
                  ("zoom.maxPercent", 300),
                  ("webgl.verbose", 'false')]
        commandline = []
        for pref, value in _prefs:
            commandline += ["--pref", "%s:%s" % (pref, value)]
        _prefs = [(i, Preferences.cast(j)) for i, j in _prefs]
        self.compare_generated(_prefs, commandline)

    def test_ini(self):

        # write the .ini file
        _ini = """[DEFAULT]
browser.startup.homepage = http://planet.mozilla.org/

[foo]
browser.startup.homepage = http://github.com/
"""
        try:
            fd, name = tempfile.mkstemp(suffix='.ini')
            os.write(fd, _ini)
            os.close(fd)
            commandline = ["--preferences", name]

            # test the [DEFAULT] section
            _prefs = {'browser.startup.homepage': 'http://planet.mozilla.org/'}
            self.compare_generated(_prefs, commandline)

            # test a specific section
            _prefs = {'browser.startup.homepage': 'http://github.com/'}
            commandline[-1] = commandline[-1] + ':foo'
            self.compare_generated(_prefs, commandline)

        finally:
            # cleanup
            os.remove(name)

    def test_ini_keep_case(self):
        """
        Read a preferences config file with a preference in camel-case style.
        Check that the read preference name has not been lower-cased
        """
        # write the .ini file
        _ini = """[DEFAULT]
general.warnOnAboutConfig = False
"""
        try:
            fd, name = tempfile.mkstemp(suffix='.ini')
            os.write(fd, _ini)
            os.close(fd)
            commandline = ["--preferences", name]

             # test the [DEFAULT] section
            _prefs = {'general.warnOnAboutConfig': 'False'}
            self.compare_generated(_prefs, commandline)

        finally:
            # cleanup
            os.remove(name)

    def test_reset_should_remove_added_prefs(self):
        """Check that when we call reset the items we expect are updated"""
        profile = Profile()
        prefs_file = os.path.join(profile.profile, 'user.js')

        # we shouldn't have any initial preferences
        initial_prefs = Preferences.read_prefs(prefs_file)
        self.assertFalse(initial_prefs)
        initial_prefs = file(prefs_file).read().strip()
        self.assertFalse(initial_prefs)

        # add some preferences
        prefs1 = [("mr.t.quotes", "i aint getting on no plane!")]
        profile.set_preferences(prefs1)
        self.assertEqual(prefs1, Preferences.read_prefs(prefs_file))
        lines = file(prefs_file).read().strip().splitlines()
        self.assertTrue(any(line.startswith('#MozRunner Prefs Start') for line in lines))
        self.assertTrue(any(line.startswith('#MozRunner Prefs End') for line in lines))

        profile.reset()
        self.assertNotEqual(prefs1,
                            Preferences.read_prefs(os.path.join(profile.profile, 'user.js')),
                            "I pity the fool who left my pref")

    def test_reset_should_keep_user_added_prefs(self):
        """Check that when we call reset the items we expect are updated"""
        profile = Profile()
        prefs_file = os.path.join(profile.profile, 'user.js')

        # we shouldn't have any initial preferences
        initial_prefs = Preferences.read_prefs(prefs_file)
        self.assertFalse(initial_prefs)
        initial_prefs = file(prefs_file).read().strip()
        self.assertFalse(initial_prefs)

        # add some preferences
        prefs1 = [("mr.t.quotes", "i aint getting on no plane!")]
        profile.set_persistent_preferences(prefs1)
        self.assertEqual(prefs1, Preferences.read_prefs(prefs_file))
        lines = file(prefs_file).read().strip().splitlines()
        self.assertTrue(any(line.startswith('#MozRunner Prefs Start') for line in lines))
        self.assertTrue(any(line.startswith('#MozRunner Prefs End') for line in lines))

        profile.reset()
        self.assertEqual(prefs1,
                         Preferences.read_prefs(os.path.join(profile.profile, 'user.js')),
                         "I pity the fool who left my pref")

    def test_magic_markers(self):
        """ensure our magic markers are working"""

        profile = Profile()
        prefs_file = os.path.join(profile.profile, 'user.js')

        # we shouldn't have any initial preferences
        initial_prefs = Preferences.read_prefs(prefs_file)
        self.assertFalse(initial_prefs)
        initial_prefs = file(prefs_file).read().strip()
        self.assertFalse(initial_prefs)

        # add some preferences
        prefs1 = [("browser.startup.homepage", "http://planet.mozilla.org/"),
                   ("zoom.minPercent", 30)]
        profile.set_preferences(prefs1)
        self.assertEqual(prefs1, Preferences.read_prefs(prefs_file))
        lines = file(prefs_file).read().strip().splitlines()
        self.assertTrue(bool([line for line in lines
                              if line.startswith('#MozRunner Prefs Start')]))
        self.assertTrue(bool([line for line in lines
                              if line.startswith('#MozRunner Prefs End')]))

        # add some more preferences
        prefs2 = [("zoom.maxPercent", 300),
                   ("webgl.verbose", 'false')]
        profile.set_preferences(prefs2)
        self.assertEqual(prefs1 + prefs2, Preferences.read_prefs(prefs_file))
        lines = file(prefs_file).read().strip().splitlines()
        self.assertTrue(len([line for line in lines
                             if line.startswith('#MozRunner Prefs Start')]) == 2)
        self.assertTrue(len([line for line in lines
                             if line.startswith('#MozRunner Prefs End')]) == 2)

        # now clean it up
        profile.clean_preferences()
        final_prefs = Preferences.read_prefs(prefs_file)
        self.assertFalse(final_prefs)
        lines = file(prefs_file).read().strip().splitlines()
        self.assertTrue('#MozRunner Prefs Start' not in lines)
        self.assertTrue('#MozRunner Prefs End' not in lines)

    def test_preexisting_preferences(self):
        """ensure you don't clobber preexisting preferences"""

        # make a pretend profile
        tempdir = tempfile.mkdtemp()

        try:
            # make a user.js
            contents = """
user_pref("webgl.enabled_for_all_sites", true);
user_pref("webgl.force-enabled", true);
"""
            user_js = os.path.join(tempdir, 'user.js')
            f = file(user_js, 'w')
            f.write(contents)
            f.close()

            # make sure you can read it
            prefs = Preferences.read_prefs(user_js)
            original_prefs = [('webgl.enabled_for_all_sites', True), ('webgl.force-enabled', True)]
            self.assertTrue(prefs == original_prefs)

            # now read this as a profile
            profile = Profile(tempdir, preferences={"browser.download.dir": "/home/jhammel"})

            # make sure the new pref is now there
            new_prefs = original_prefs[:] + [("browser.download.dir", "/home/jhammel")]
            prefs = Preferences.read_prefs(user_js)
            self.assertTrue(prefs == new_prefs)

            # clean up the added preferences
            profile.cleanup()
            del profile

            # make sure you have the original preferences
            prefs = Preferences.read_prefs(user_js)
            self.assertTrue(prefs == original_prefs)
        finally:
            shutil.rmtree(tempdir)

    def test_json(self):
        _prefs = {"browser.startup.homepage": "http://planet.mozilla.org/"}
        json = '{"browser.startup.homepage": "http://planet.mozilla.org/"}'

        # just repr it...could use the json module but we don't need it here
        with mozfile.NamedTemporaryFile(suffix='.json') as f:
            f.write(json)
            f.flush()

            commandline = ["--preferences", f.name]
            self.compare_generated(_prefs, commandline)

    def test_prefs_write(self):
        """test that the Preferences.write() method correctly serializes preferences"""

        _prefs = {'browser.startup.homepage': "http://planet.mozilla.org",
                  'zoom.minPercent': 30,
                  'zoom.maxPercent': 300}

        # make a Preferences manager with the testing preferences
        preferences = Preferences(_prefs)

        # write them to a temporary location
        path = None
        read_prefs = None
        try:
            with mozfile.NamedTemporaryFile(suffix='.js', delete=False) as f:
                path = f.name
                preferences.write(f, _prefs)

            # read them back and ensure we get what we put in
            read_prefs = dict(Preferences.read_prefs(path))

        finally:
            # cleanup
            if path and os.path.exists(path):
                os.remove(path)

        self.assertEqual(read_prefs, _prefs)

    def test_read_prefs_with_comments(self):
        """test reading preferences from a prefs.js file that contains comments"""

        path = os.path.join(here, 'files', 'prefs_with_comments.js')
        self.assertEqual(dict(Preferences.read_prefs(path)), self._prefs_with_comments)

    def test_read_prefs_with_interpolation(self):
        """test reading preferences from a prefs.js file whose values
        require interpolation"""

        expected_prefs = {
            "browser.foo": "http://server-name",
            "zoom.minPercent": 30,
            "webgl.verbose": "false",
            "browser.bar": "somethingxyz"
            }
        values = {
            "server": "server-name",
            "abc": "something"
            }
        path = os.path.join(here, 'files', 'prefs_with_interpolation.js')
        read_prefs = Preferences.read_prefs(path, interpolation=values)
        self.assertEqual(dict(read_prefs), expected_prefs)

    def test_read_prefs_ttw(self):
        """test reading preferences through the web via mozhttpd"""

        # create a MozHttpd instance
        docroot = os.path.join(here, 'files')
        host = '127.0.0.1'
        port = 8888
        httpd = mozhttpd.MozHttpd(host=host, port=port, docroot=docroot)

        # create a preferences instance
        prefs = Preferences()

        try:
            # start server
            httpd.start(block=False)

            # read preferences through the web
            read = prefs.read_prefs('http://%s:%d/prefs_with_comments.js' % (host, port))
            self.assertEqual(dict(read), self._prefs_with_comments)
        finally:
            httpd.stop()

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