# 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/.

from __future__ import unicode_literals

import os
import shutil
import unittest

from mozunit import main

from mozbuild.frontend.reader import (
    MozbuildSandbox,
    SandboxCalledError,
)

from mozbuild.frontend.sandbox import (
    SandboxExecutionError,
    SandboxLoadError,
)

from mozbuild.frontend.sandbox_symbols import (
    FUNCTIONS,
    SPECIAL_VARIABLES,
    VARIABLES,
)

from mozbuild.test.common import MockConfig


test_data_path = os.path.abspath(os.path.dirname(__file__))
test_data_path = os.path.join(test_data_path, 'data')


class TestSandbox(unittest.TestCase):
    def sandbox(self, relpath='moz.build', data_path=None):
        config = None

        if data_path is not None:
            config = MockConfig(os.path.join(test_data_path, data_path))
        else:
            config = MockConfig()

        return MozbuildSandbox(config, config.child_path(relpath))

    def test_default_state(self):
        sandbox = self.sandbox()
        config = sandbox.config

        self.assertEqual(sandbox['TOPSRCDIR'], config.topsrcdir)
        self.assertEqual(sandbox['TOPOBJDIR'],
            os.path.abspath(config.topobjdir))
        self.assertEqual(sandbox['RELATIVEDIR'], '')
        self.assertEqual(sandbox['SRCDIR'], config.topsrcdir)
        self.assertEqual(sandbox['OBJDIR'],
            os.path.abspath(config.topobjdir).replace(os.sep, '/'))

    def test_symbol_presence(self):
        # Ensure no discrepancies between the master symbol table and what's in
        # the sandbox.
        sandbox = self.sandbox()

        all_symbols = set()
        all_symbols |= set(FUNCTIONS.keys())
        all_symbols |= set(SPECIAL_VARIABLES.keys())

        for symbol in sandbox:
            self.assertIn(symbol, all_symbols)
            all_symbols.remove(symbol)

        self.assertEqual(len(all_symbols), 0)

    def test_path_calculation(self):
        sandbox = self.sandbox('foo/bar/moz.build')
        config = sandbox.config

        self.assertEqual(sandbox['RELATIVEDIR'], 'foo/bar')
        self.assertEqual(sandbox['SRCDIR'], '/'.join([config.topsrcdir,
            'foo/bar']))
        self.assertEqual(sandbox['OBJDIR'],
            os.path.abspath('/'.join([config.topobjdir, 'foo/bar'])).replace(os.sep, '/'))

    def test_config_access(self):
        sandbox = self.sandbox()
        config = sandbox.config

        self.assertIn('CONFIG', sandbox)
        self.assertEqual(sandbox['CONFIG']['MOZ_TRUE'], '1')
        self.assertEqual(sandbox['CONFIG']['MOZ_FOO'], config.substs['MOZ_FOO'])

        # Access to an undefined substitution should return None.
        self.assertNotIn('MISSING', sandbox['CONFIG'])
        self.assertIsNone(sandbox['CONFIG']['MISSING'])

        # Should shouldn't be allowed to assign to the config.
        with self.assertRaises(Exception):
            sandbox['CONFIG']['FOO'] = ''

    def test_dict_interface(self):
        sandbox = self.sandbox()
        config = sandbox.config

        self.assertFalse('foo' in sandbox)
        self.assertFalse('FOO' in sandbox)

        self.assertTrue(sandbox.get('foo', True))
        self.assertEqual(sandbox.get('TOPSRCDIR'), config.topsrcdir)
        self.assertGreater(len(sandbox), 6)

        for key in sandbox:
            continue

        for key in sandbox.iterkeys():
            continue

    def test_exec_source_success(self):
        sandbox = self.sandbox()

        sandbox.exec_source('foo = True', 'foo.py')

        self.assertNotIn('foo', sandbox)
        self.assertEqual(sandbox.main_path, 'foo.py')
        self.assertEqual(sandbox.all_paths, set(['foo.py']))

    def test_exec_compile_error(self):
        sandbox = self.sandbox()

        with self.assertRaises(SandboxExecutionError) as se:
            sandbox.exec_source('2f23;k;asfj', 'foo.py')

        self.assertEqual(se.exception.file_stack, ['foo.py'])
        self.assertIsInstance(se.exception.exc_value, SyntaxError)
        self.assertEqual(sandbox.main_path, 'foo.py')

    def test_exec_import_denied(self):
        sandbox = self.sandbox()

        with self.assertRaises(SandboxExecutionError) as se:
            sandbox.exec_source('import sys', 'import.py')

        self.assertIsInstance(se.exception, SandboxExecutionError)
        self.assertEqual(se.exception.exc_type, ImportError)

    def test_exec_source_multiple(self):
        sandbox = self.sandbox()

        sandbox.exec_source('DIRS = ["foo"]', 'foo.py')
        sandbox.exec_source('DIRS = ["bar"]', 'foo.py')

        self.assertEqual(sandbox['DIRS'], ['bar'])

    def test_exec_source_illegal_key_set(self):
        sandbox = self.sandbox()

        with self.assertRaises(SandboxExecutionError) as se:
            sandbox.exec_source('ILLEGAL = True', 'foo.py')

        e = se.exception
        self.assertIsInstance(e.exc_value, KeyError)

        e = se.exception.exc_value
        self.assertEqual(e.args[0], 'global_ns')
        self.assertEqual(e.args[1], 'set_unknown')

    def test_add_tier_dir_regular_str(self):
        sandbox = self.sandbox()

        sandbox.exec_source('add_tier_dir("t1", "foo")', 'foo.py')

        self.assertEqual(sandbox['TIERS']['t1'],
            {'regular': ['foo'], 'static': []})

    def test_add_tier_dir_regular_list(self):
        sandbox = self.sandbox()

        sandbox.exec_source('add_tier_dir("t1", ["foo", "bar"])', 'foo.py')

        self.assertEqual(sandbox['TIERS']['t1'],
            {'regular': ['foo', 'bar'], 'static': []})

    def test_add_tier_dir_static(self):
        sandbox = self.sandbox()

        sandbox.exec_source('add_tier_dir("t1", "foo", static=True)', 'foo.py')

        self.assertEqual(sandbox['TIERS']['t1'],
            {'regular': [], 'static': ['foo']})

    def test_tier_order(self):
        sandbox = self.sandbox()

        source = '''
add_tier_dir('t1', 'foo')
add_tier_dir('t1', 'bar')
add_tier_dir('t2', 'baz', static=True)
add_tier_dir('t3', 'biz')
add_tier_dir('t1', 'bat', static=True)
'''

        sandbox.exec_source(source, 'foo.py')

        self.assertEqual([k for k in sandbox['TIERS'].keys()], ['t1', 't2', 't3'])

    def test_tier_multiple_registration(self):
        sandbox = self.sandbox()

        sandbox.exec_source('add_tier_dir("t1", "foo")', 'foo.py')

        with self.assertRaises(SandboxExecutionError):
            sandbox.exec_source('add_tier_dir("t1", "foo")', 'foo.py')

    def test_include_basic(self):
        sandbox = self.sandbox(data_path='include-basic')

        sandbox.exec_file('moz.build')

        self.assertEqual(sandbox['DIRS'], ['foo', 'bar'])
        self.assertEqual(sandbox.main_path,
            os.path.join(sandbox['TOPSRCDIR'], 'moz.build'))
        self.assertEqual(len(sandbox.all_paths), 2)

    def test_include_outside_topsrcdir(self):
        sandbox = self.sandbox(data_path='include-outside-topsrcdir')

        with self.assertRaises(SandboxLoadError) as se:
            sandbox.exec_file('relative.build')

        expected = os.path.join(test_data_path, 'moz.build')
        self.assertEqual(se.exception.illegal_path, expected)

    def test_include_error_stack(self):
        # Ensure the path stack is reported properly in exceptions.
        sandbox = self.sandbox(data_path='include-file-stack')

        with self.assertRaises(SandboxExecutionError) as se:
            sandbox.exec_file('moz.build')

        e = se.exception
        self.assertIsInstance(e.exc_value, KeyError)

        args = e.exc_value.args
        self.assertEqual(args[0], 'global_ns')
        self.assertEqual(args[1], 'set_unknown')
        self.assertEqual(args[2], 'ILLEGAL')

        expected_stack = [os.path.join(sandbox.config.topsrcdir, p) for p in [
            'moz.build', 'included-1.build', 'included-2.build']]

        self.assertEqual(e.file_stack, expected_stack)

    def test_include_missing(self):
        sandbox = self.sandbox(data_path='include-missing')

        with self.assertRaises(SandboxLoadError) as sle:
            sandbox.exec_file('moz.build')

        self.assertIsNotNone(sle.exception.read_error)

    def test_include_relative_from_child_dir(self):
        # A relative path from a subdirectory should be relative from that
        # child directory.
        sandbox = self.sandbox(data_path='include-relative-from-child')
        sandbox.exec_file('child/child.build')
        self.assertEqual(sandbox['DIRS'], ['foo'])

        sandbox = self.sandbox(data_path='include-relative-from-child')
        sandbox.exec_file('child/child2.build')
        self.assertEqual(sandbox['DIRS'], ['foo'])

    def test_include_topsrcdir_relative(self):
        # An absolute path for include() is relative to topsrcdir.

        sandbox = self.sandbox(data_path='include-topsrcdir-relative')
        sandbox.exec_file('moz.build')

        self.assertEqual(sandbox['DIRS'], ['foo'])

    def test_external_make_dirs(self):
        sandbox = self.sandbox()
        sandbox.exec_source('EXTERNAL_MAKE_DIRS += ["foo"]', 'test.py')
        sandbox.exec_source('PARALLEL_EXTERNAL_MAKE_DIRS += ["bar"]', 'test.py')

        self.assertEqual(sandbox['EXTERNAL_MAKE_DIRS'], ['foo'])
        self.assertEqual(sandbox['PARALLEL_EXTERNAL_MAKE_DIRS'], ['bar'])

    def test_error(self):
        sandbox = self.sandbox()

        with self.assertRaises(SandboxCalledError) as sce:
            sandbox.exec_source('error("This is an error.")', 'test.py')

        e = sce.exception
        self.assertEqual(e.message, 'This is an error.')

    def test_substitute_config_files(self):
        sandbox = self.sandbox()

        sandbox.exec_source('CONFIGURE_SUBST_FILES += ["bar", "foo"]',
            'test.py')
        self.assertEqual(sandbox['CONFIGURE_SUBST_FILES'], ['bar', 'foo'])

    def test_invalid_utf8_substs(self):
        """Ensure invalid UTF-8 in substs is converted with an error."""

        config = MockConfig()
        # This is really mbcs. It's a bunch of invalid UTF-8.
        config.substs['BAD_UTF8'] = b'\x83\x81\x83\x82\x3A'

        sandbox = MozbuildSandbox(config, '/foo/moz.build')

        self.assertEqual(sandbox['CONFIG']['BAD_UTF8'],
            u'\ufffd\ufffd\ufffd\ufffd:')

    def test_invalid_exports_set_base(self):
        sandbox = self.sandbox()

        with self.assertRaises(SandboxExecutionError) as se:
            sandbox.exec_source('EXPORTS = "foo.h"', 'foo.py')

        self.assertEqual(se.exception.exc_type, ValueError)

if __name__ == '__main__':
    main()
