# 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 unittest
import mozunit
import os
from mozpack.packager import (
    preprocess_manifest,
    CallDeque,
    Component,
    SimplePackager,
    SimpleManifestSink,
)
from mozpack.files import GeneratedFile
from mozpack.chrome.manifest import (
    ManifestBinaryComponent,
    ManifestContent,
    ManifestResource,
)
from mozunit import MockedOpen
from mozbuild.preprocessor import Preprocessor
from mozpack.errors import (
    errors,
    ErrorMessage,
)
import mozpack.path as mozpath

MANIFEST = '''
bar/*
[foo]
foo/*
-foo/bar
chrome.manifest
[zot destdir="destdir"]
foo/zot
; comment
#ifdef baz
[baz]
baz@SUFFIX@
#endif
'''


class TestPreprocessManifest(unittest.TestCase):
    MANIFEST_PATH = os.path.join(os.path.abspath(os.curdir), 'manifest')

    EXPECTED_LOG = [
        ((MANIFEST_PATH, 2), 'add', '', 'bar/*'),
        ((MANIFEST_PATH, 4), 'add', 'foo', 'foo/*'),
        ((MANIFEST_PATH, 5), 'remove', 'foo', 'foo/bar'),
        ((MANIFEST_PATH, 6), 'add', 'foo', 'chrome.manifest'),
        ((MANIFEST_PATH, 8), 'add', 'zot destdir="destdir"', 'foo/zot'),
    ]

    def setUp(self):
        class MockSink(object):
            def __init__(self):
                self.log = []

            def add(self, component, path):
                self._log(errors.get_context(), 'add', repr(component), path)

            def remove(self, component, path):
                self._log(errors.get_context(), 'remove', repr(component), path)

            def _log(self, *args):
                self.log.append(args)

        self.sink = MockSink()

    def test_preprocess_manifest(self):
        with MockedOpen({'manifest': MANIFEST}):
            preprocess_manifest(self.sink, 'manifest')
        self.assertEqual(self.sink.log, self.EXPECTED_LOG)

    def test_preprocess_manifest_missing_define(self):
        with MockedOpen({'manifest': MANIFEST}):
            self.assertRaises(
                Preprocessor.Error,
                preprocess_manifest,
                self.sink,
                'manifest',
                {'baz': 1}
            )

    def test_preprocess_manifest_defines(self):
        with MockedOpen({'manifest': MANIFEST}):
            preprocess_manifest(self.sink, 'manifest',
                                {'baz': 1, 'SUFFIX': '.exe'})
        self.assertEqual(self.sink.log, self.EXPECTED_LOG +
                         [((self.MANIFEST_PATH, 12), 'add', 'baz', 'baz.exe')])


class MockFinder(object):
    def __init__(self, files):
        self.files = files
        self.log = []

    def find(self, path):
        self.log.append(path)
        for f in sorted(self.files):
            if mozpath.match(f, path):
                yield f, self.files[f]

    def __iter__(self):
        return self.find('')


class MockFormatter(object):
    def __init__(self):
        self.log = []

    def add_base(self, *args):
        self._log(errors.get_context(), 'add_base', *args)

    def add_manifest(self, *args):
        self._log(errors.get_context(), 'add_manifest', *args)

    def add_interfaces(self, *args):
        self._log(errors.get_context(), 'add_interfaces', *args)

    def add(self, *args):
        self._log(errors.get_context(), 'add', *args)

    def _log(self, *args):
        self.log.append(args)


class TestSimplePackager(unittest.TestCase):
    def test_simple_packager(self):
        class GeneratedFileWithPath(GeneratedFile):
            def __init__(self, path, content):
                GeneratedFile.__init__(self, content)
                self.path = path

        formatter = MockFormatter()
        packager = SimplePackager(formatter)
        curdir = os.path.abspath(os.curdir)
        file = GeneratedFileWithPath(os.path.join(curdir, 'foo',
                                                  'bar.manifest'),
                                     'resource bar bar/\ncontent bar bar/')
        with errors.context('manifest', 1):
            packager.add('foo/bar.manifest', file)

        file = GeneratedFileWithPath(os.path.join(curdir, 'foo',
                                                  'baz.manifest'),
                                     'resource baz baz/')
        with errors.context('manifest', 2):
            packager.add('bar/baz.manifest', file)

        with errors.context('manifest', 3):
            packager.add('qux/qux.manifest',
                         GeneratedFile(''.join([
                            'resource qux qux/\n',
                            'binary-component qux.so\n',
                         ])))
        bar_xpt = GeneratedFile('bar.xpt')
        qux_xpt = GeneratedFile('qux.xpt')
        foo_html = GeneratedFile('foo_html')
        bar_html = GeneratedFile('bar_html')
        with errors.context('manifest', 4):
            packager.add('foo/bar.xpt', bar_xpt)
        with errors.context('manifest', 5):
            packager.add('foo/bar/foo.html', foo_html)
            packager.add('foo/bar/bar.html', bar_html)

        file = GeneratedFileWithPath(os.path.join(curdir, 'foo.manifest'),
                                     ''.join([
                                         'manifest foo/bar.manifest\n',
                                         'manifest bar/baz.manifest\n',
                                     ]))
        with errors.context('manifest', 6):
            packager.add('foo.manifest', file)
        with errors.context('manifest', 7):
            packager.add('foo/qux.xpt', qux_xpt)

        file = GeneratedFileWithPath(os.path.join(curdir, 'addon',
                                                  'chrome.manifest'),
                                     'resource hoge hoge/')
        with errors.context('manifest', 8):
            packager.add('addon/chrome.manifest', file)

        install_rdf = GeneratedFile('<RDF></RDF>')
        with errors.context('manifest', 9):
            packager.add('addon/install.rdf', install_rdf)

        with errors.context('manifest', 10):
            packager.add('addon2/install.rdf', install_rdf)
            packager.add('addon2/chrome.manifest',
                         GeneratedFile('binary-component addon2.so'))

        with errors.context('manifest', 11):
            packager.add('addon3/install.rdf', install_rdf)
            packager.add('addon3/chrome.manifest', GeneratedFile(
                'manifest components/components.manifest'))
            packager.add('addon3/components/components.manifest',
                         GeneratedFile('binary-component addon3.so'))

        with errors.context('manifest', 12):
            install_rdf_addon4 = GeneratedFile(
                '<RDF>\n<...>\n<em:unpack>true</em:unpack>\n<...>\n</RDF>')
            packager.add('addon4/install.rdf', install_rdf_addon4)

        with errors.context('manifest', 13):
            install_rdf_addon5 = GeneratedFile(
                '<RDF>\n<...>\n<em:unpack>false</em:unpack>\n<...>\n</RDF>')
            packager.add('addon5/install.rdf', install_rdf_addon5)

        with errors.context('manifest', 14):
            install_rdf_addon6 = GeneratedFile(
                '<RDF>\n<... em:unpack=true>\n<...>\n</RDF>')
            packager.add('addon6/install.rdf', install_rdf_addon6)

        with errors.context('manifest', 15):
            install_rdf_addon7 = GeneratedFile(
                '<RDF>\n<... em:unpack=false>\n<...>\n</RDF>')
            packager.add('addon7/install.rdf', install_rdf_addon7)

        with errors.context('manifest', 16):
            install_rdf_addon8 = GeneratedFile(
                '<RDF>\n<... em:unpack="true">\n<...>\n</RDF>')
            packager.add('addon8/install.rdf', install_rdf_addon8)

        with errors.context('manifest', 17):
            install_rdf_addon9 = GeneratedFile(
                '<RDF>\n<... em:unpack="false">\n<...>\n</RDF>')
            packager.add('addon9/install.rdf', install_rdf_addon9)

        with errors.context('manifest', 18):
            install_rdf_addon10 = GeneratedFile(
                '<RDF>\n<... em:unpack=\'true\'>\n<...>\n</RDF>')
            packager.add('addon10/install.rdf', install_rdf_addon10)

        with errors.context('manifest', 19):
            install_rdf_addon11 = GeneratedFile(
                '<RDF>\n<... em:unpack=\'false\'>\n<...>\n</RDF>')
            packager.add('addon11/install.rdf', install_rdf_addon11)

        self.assertEqual(formatter.log, [])

        with errors.context('dummy', 1):
            packager.close()
        self.maxDiff = None
        # The formatter is expected to reorder the manifest entries so that
        # chrome entries appear before the others.
        self.assertEqual(formatter.log, [
            (('dummy', 1), 'add_base', '', False),
            (('dummy', 1), 'add_base', 'addon', True),
            (('dummy', 1), 'add_base', 'addon10', 'unpacked'),
            (('dummy', 1), 'add_base', 'addon11', True),
            (('dummy', 1), 'add_base', 'addon2', 'unpacked'),
            (('dummy', 1), 'add_base', 'addon3', 'unpacked'),
            (('dummy', 1), 'add_base', 'addon4', 'unpacked'),
            (('dummy', 1), 'add_base', 'addon5', True),
            (('dummy', 1), 'add_base', 'addon6', 'unpacked'),
            (('dummy', 1), 'add_base', 'addon7', True),
            (('dummy', 1), 'add_base', 'addon8', 'unpacked'),
            (('dummy', 1), 'add_base', 'addon9', True),
            (('dummy', 1), 'add_base', 'qux', False),
            ((os.path.join(curdir, 'foo', 'bar.manifest'), 2),
             'add_manifest', ManifestContent('foo', 'bar', 'bar/')),
            ((os.path.join(curdir, 'foo', 'bar.manifest'), 1),
             'add_manifest', ManifestResource('foo', 'bar', 'bar/')),
            (('bar/baz.manifest', 1),
             'add_manifest', ManifestResource('bar', 'baz', 'baz/')),
            (('qux/qux.manifest', 1),
             'add_manifest', ManifestResource('qux', 'qux', 'qux/')),
            (('qux/qux.manifest', 2),
             'add_manifest', ManifestBinaryComponent('qux', 'qux.so')),
            (('manifest', 4), 'add_interfaces', 'foo/bar.xpt', bar_xpt),
            (('manifest', 7), 'add_interfaces', 'foo/qux.xpt', qux_xpt),
            ((os.path.join(curdir, 'addon', 'chrome.manifest'), 1),
             'add_manifest', ManifestResource('addon', 'hoge', 'hoge/')),
            (('addon2/chrome.manifest', 1), 'add_manifest',
             ManifestBinaryComponent('addon2', 'addon2.so')),
            (('addon3/components/components.manifest', 1), 'add_manifest',
             ManifestBinaryComponent('addon3/components', 'addon3.so')),
            (('manifest', 5), 'add', 'foo/bar/foo.html', foo_html),
            (('manifest', 5), 'add', 'foo/bar/bar.html', bar_html),
            (('manifest', 9), 'add', 'addon/install.rdf', install_rdf),
            (('manifest', 10), 'add', 'addon2/install.rdf', install_rdf),
            (('manifest', 11), 'add', 'addon3/install.rdf', install_rdf),
            (('manifest', 12), 'add', 'addon4/install.rdf',
             install_rdf_addon4),
            (('manifest', 13), 'add', 'addon5/install.rdf',
             install_rdf_addon5),
            (('manifest', 14), 'add', 'addon6/install.rdf',
             install_rdf_addon6),
            (('manifest', 15), 'add', 'addon7/install.rdf',
             install_rdf_addon7),
            (('manifest', 16), 'add', 'addon8/install.rdf',
             install_rdf_addon8),
            (('manifest', 17), 'add', 'addon9/install.rdf',
             install_rdf_addon9),
            (('manifest', 18), 'add', 'addon10/install.rdf',
             install_rdf_addon10),
            (('manifest', 19), 'add', 'addon11/install.rdf',
             install_rdf_addon11),
        ])

        self.assertEqual(packager.get_bases(),
                         set(['', 'addon', 'addon2', 'addon3', 'addon4',
                              'addon5', 'addon6', 'addon7', 'addon8',
                              'addon9', 'addon10', 'addon11', 'qux']))
        self.assertEqual(packager.get_bases(addons=False), set(['', 'qux']))

    def test_simple_packager_manifest_consistency(self):
        formatter = MockFormatter()
        # bar/ is detected as an addon because of install.rdf, but top-level
        # includes a manifest inside bar/.
        packager = SimplePackager(formatter)
        packager.add('base.manifest', GeneratedFile(
            'manifest foo/bar.manifest\n'
            'manifest bar/baz.manifest\n'
        ))
        packager.add('foo/bar.manifest', GeneratedFile('resource bar bar'))
        packager.add('bar/baz.manifest', GeneratedFile('resource baz baz'))
        packager.add('bar/install.rdf', GeneratedFile(''))

        with self.assertRaises(ErrorMessage) as e:
            packager.close()

        self.assertEqual(e.exception.message,
            'Error: "bar/baz.manifest" is included from "base.manifest", '
            'which is outside "bar"')

        # bar/ is detected as a separate base because of chrome.manifest that
        # is included nowhere, but top-level includes another manifest inside
        # bar/.
        packager = SimplePackager(formatter)
        packager.add('base.manifest', GeneratedFile(
            'manifest foo/bar.manifest\n'
            'manifest bar/baz.manifest\n'
        ))
        packager.add('foo/bar.manifest', GeneratedFile('resource bar bar'))
        packager.add('bar/baz.manifest', GeneratedFile('resource baz baz'))
        packager.add('bar/chrome.manifest', GeneratedFile('resource baz baz'))

        with self.assertRaises(ErrorMessage) as e:
            packager.close()

        self.assertEqual(e.exception.message,
            'Error: "bar/baz.manifest" is included from "base.manifest", '
            'which is outside "bar"')

        # bar/ is detected as a separate base because of chrome.manifest that
        # is included nowhere, but chrome.manifest includes baz.manifest from
        # the same directory. This shouldn't error out.
        packager = SimplePackager(formatter)
        packager.add('base.manifest', GeneratedFile(
            'manifest foo/bar.manifest\n'
        ))
        packager.add('foo/bar.manifest', GeneratedFile('resource bar bar'))
        packager.add('bar/baz.manifest', GeneratedFile('resource baz baz'))
        packager.add('bar/chrome.manifest',
                     GeneratedFile('manifest baz.manifest'))
        packager.close()


class TestSimpleManifestSink(unittest.TestCase):
    def test_simple_manifest_parser(self):
        formatter = MockFormatter()
        foobar = GeneratedFile('foobar')
        foobaz = GeneratedFile('foobaz')
        fooqux = GeneratedFile('fooqux')
        foozot = GeneratedFile('foozot')
        finder = MockFinder({
            'bin/foo/bar': foobar,
            'bin/foo/baz': foobaz,
            'bin/foo/qux': fooqux,
            'bin/foo/zot': foozot,
            'bin/foo/chrome.manifest': GeneratedFile('resource foo foo/'),
            'bin/chrome.manifest':
            GeneratedFile('manifest foo/chrome.manifest'),
        })
        parser = SimpleManifestSink(finder, formatter)
        component0 = Component('component0')
        component1 = Component('component1')
        component2 = Component('component2', destdir='destdir')
        parser.add(component0, 'bin/foo/b*')
        parser.add(component1, 'bin/foo/qux')
        parser.add(component1, 'bin/foo/chrome.manifest')
        parser.add(component2, 'bin/foo/zot')
        self.assertRaises(ErrorMessage, parser.add, 'component1', 'bin/bar')

        self.assertEqual(formatter.log, [])
        parser.close()
        self.assertEqual(formatter.log, [
            (None, 'add_base', '', False),
            (('foo/chrome.manifest', 1),
             'add_manifest', ManifestResource('foo', 'foo', 'foo/')),
            (None, 'add', 'foo/bar', foobar),
            (None, 'add', 'foo/baz', foobaz),
            (None, 'add', 'foo/qux', fooqux),
            (None, 'add', 'destdir/foo/zot', foozot),
        ])

        self.assertEqual(finder.log, [
            'bin/foo/b*',
            'bin/foo/qux',
            'bin/foo/chrome.manifest',
            'bin/foo/zot',
            'bin/bar',
            'bin/chrome.manifest'
        ])


class TestCallDeque(unittest.TestCase):
    def test_call_deque(self):
        class Logger(object):
            def __init__(self):
                self._log = []

            def log(self, str):
                self._log.append(str)

            @staticmethod
            def staticlog(logger, str):
                logger.log(str)

        def do_log(logger, str):
            logger.log(str)

        logger = Logger()
        d = CallDeque()
        d.append(logger.log, 'foo')
        d.append(logger.log, 'bar')
        d.append(logger.staticlog, logger, 'baz')
        d.append(do_log, logger, 'qux')
        self.assertEqual(logger._log, [])
        d.execute()
        self.assertEqual(logger._log, ['foo', 'bar', 'baz', 'qux'])


class TestComponent(unittest.TestCase):
    def do_split(self, string, name, options):
        n, o = Component._split_component_and_options(string)
        self.assertEqual(name, n)
        self.assertEqual(options, o)

    def test_component_split_component_and_options(self):
        self.do_split('component', 'component', {})
        self.do_split('trailingspace ', 'trailingspace', {})
        self.do_split(' leadingspace', 'leadingspace', {})
        self.do_split(' trim ', 'trim', {})
        self.do_split(' trim key="value"', 'trim', {'key':'value'})
        self.do_split(' trim empty=""', 'trim', {'empty':''})
        self.do_split(' trim space=" "', 'trim', {'space':' '})
        self.do_split('component key="value"  key2="second" ',
                      'component', {'key':'value', 'key2':'second'})
        self.do_split( 'trim key="  value with spaces   "  key2="spaces again"',
                       'trim', {'key':'  value with spaces   ', 'key2': 'spaces again'})

    def do_split_error(self, string):
        self.assertRaises(ValueError, Component._split_component_and_options, string)

    def test_component_split_component_and_options_errors(self):
        self.do_split_error('"component')
        self.do_split_error('comp"onent')
        self.do_split_error('component"')
        self.do_split_error('"component"')
        self.do_split_error('=component')
        self.do_split_error('comp=onent')
        self.do_split_error('component=')
        self.do_split_error('key="val"')
        self.do_split_error('component key=')
        self.do_split_error('component key="val')
        self.do_split_error('component key=val"')
        self.do_split_error('component key="val" x')
        self.do_split_error('component x key="val"')
        self.do_split_error('component key1="val" x key2="val"')

    def do_from_string(self, string, name, destdir=''):
        component = Component.from_string(string)
        self.assertEqual(name, component.name)
        self.assertEqual(destdir, component.destdir)

    def test_component_from_string(self):
        self.do_from_string('component', 'component')
        self.do_from_string('component-with-hyphen', 'component-with-hyphen')
        self.do_from_string('component destdir="foo/bar"', 'component', 'foo/bar')
        self.do_from_string('component destdir="bar spc"', 'component', 'bar spc')
        self.assertRaises(ErrorMessage, Component.from_string, '')
        self.assertRaises(ErrorMessage, Component.from_string, 'component novalue=')
        self.assertRaises(ErrorMessage, Component.from_string, 'component badoption=badvalue')


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