# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See https://swift.org/LICENSE.txt for license information
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors


from __future__ import unicode_literals

import os

from .utils import TestCase, UTILS_PATH, add_metaclass
from .. import presets
from ..presets import Preset, PresetParser

try:
    # Python 2
    import ConfigParser as configparser
except ImportError:
    import configparser


PRESET_FILES = [
    os.path.join(UTILS_PATH, 'build-presets.ini'),
]

PRESET_DEFAULTS = {
    'darwin_toolchain_alias': 'Alias',
    'darwin_toolchain_bundle_identifier': 'BundleIdentifier',
    'darwin_toolchain_display_name': 'DisplayName',
    'darwin_toolchain_display_name_short': 'DispalyNameShort',
    'darwin_toolchain_version': '1.0',
    'darwin_toolchain_xctoolchain_name': 'default',
    'extra_swift_args': '',
    'install_destdir': '/tmp/install',
    'install_symroot': '/tmp/install/symroot',
    'install_toolchain_dir': '/tmp/install/toolchain',
    'installable_package': '/tmp/install/pkg',
    'swift_install_destdir': '/tmp/install/swift',
    'symbols_package': '/path/to/symbols/package',
    'ndk_path': '/path/to/ndk',
    'arm_dir': '/path/to/arm',
}

SAMPLE_PRESET = """
[preset: sample]

# This is a comment

ios
tvos
watchos
test
validation-test
lit-args=-v
compiler-vendor=apple

# The '--' argument is now unnecessary
dash-dash

verbose-build
build-ninja

# Default interpolation
install-symroot=%(install_symroot)s
"""

IGNORED_SECTION = """
[section_name]

random-options=1
"""

MIXIN_ORDER_PRESETS = """
[preset: test_mixin]
first-opt=0
second-opt=1


[preset: test]
first-opt=1
mixin-preset=test_mixin
second-opt=2
"""

INTERPOLATED_PRESET = """
[preset: test]

install-symroot=%(install_symroot)s
"""

DUPLICATE_PRESET_NAMES = """
[preset: test]
ios


[preset: test]
tvos
"""

DUPLICATE_PRESET_OPTIONS = """
[preset: test]

ios
ios
"""


# -----------------------------------------------------------------------------

class TestPreset(TestCase):

    def test_format_args(self):
        preset = Preset('sample', [('--ios', None), ('--test', '1')])

        self.assertEqual(preset.format_args(), ['--ios', '--test=1'])


# -----------------------------------------------------------------------------

class TestPresetParserMeta(type):
    """Metaclass used to dynamically generate test methods to validate all of
    the available presets.
    """

    def __new__(cls, name, bases, attrs):
        preset_parser = PresetParser()
        preset_parser.read(PRESET_FILES)

        # Generate tests for each preset
        for preset_name in preset_parser.preset_names():
            test_name = 'test_get_preset_' + preset_name
            attrs[test_name] = cls.generate_get_preset_test(
                preset_parser, preset_name)

        return super(TestPresetParserMeta, cls).__new__(
            cls, name, bases, attrs)

    @classmethod
    def generate_get_preset_test(cls, preset_parser, preset_name):
        def test(self):
            preset_parser.get_preset(preset_name, vars=PRESET_DEFAULTS)

        return test


@add_metaclass(TestPresetParserMeta)
class TestPresetParser(TestCase):

    def test_read(self):
        parser = PresetParser()
        parser.read(PRESET_FILES)

    def test_read_invalid_files(self):
        parser = PresetParser()

        with self.assertRaises(presets.UnparsedFilesError) as cm:
            parser.read(['nonsense-presets.ini'])

        e = cm.exception
        self.assertListEqual(e.filenames, ['nonsense-presets.ini'])

    def test_read_file(self):
        parser = PresetParser()

        with self.assertNotRaises():
            parser.read_file(PRESET_FILES[0])

    def test_read_string(self):
        parser = PresetParser()
        parser.read_string(SAMPLE_PRESET)

        preset = parser.get_preset('sample', vars={'install_symroot': '/tmp'})
        self.assertIsNotNone(preset)
        self.assertEqual(preset.name, 'sample')
        self.assertListEqual(preset.args, [
            ('--ios', None),
            ('--tvos', None),
            ('--watchos', None),
            ('--test', None),
            ('--validation-test', None),
            ('--lit-args', '-v'),
            ('--compiler-vendor', 'apple'),
            ('--verbose-build', None),
            ('--build-ninja', None),
            ('--install-symroot', '/tmp')
        ])

    def test_parser_ignores_non_preset_sections(self):
        parser = PresetParser()

        parser.read_string(IGNORED_SECTION)
        self.assertEqual(len(parser._presets), 0)

    def test_mixin_expansion_preserves_argument_order(self):
        """Mixins should be expanded in-place.
        """

        parser = PresetParser()

        parser.read_string(MIXIN_ORDER_PRESETS)

        preset = parser.get_preset('test')
        self.assertListEqual(preset.format_args(), [
            '--first-opt=1',

            # Mixin arguments
            '--first-opt=0',
            '--second-opt=1',

            '--second-opt=2',
        ])

    def test_interpolation_error(self):
        parser = PresetParser()
        parser.read_string(INTERPOLATED_PRESET)

        with self.assertRaises(presets.InterpolationError) as cm:
            parser.get_preset('test')

        e = cm.exception
        self.assertEqual(e.preset_name, 'test')
        self.assertEqual(e.option, '--install-symroot')
        self.assertEqual(e.rawval, '%(install_symroot)s')
        self.assertEqual(e.reference, 'install_symroot')

    def test_duplicate_option_error(self):
        # Skip test if using the Python 2 ConfigParser module
        if not hasattr(configparser, 'DuplicateOptionError'):
            return

        parser = PresetParser()

        with self.assertRaises(presets.DuplicateOptionError) as cm:
            parser.read_string(DUPLICATE_PRESET_OPTIONS)

        e = cm.exception
        self.assertEqual(e.preset_name, 'test')
        self.assertEqual(e.option, 'ios')

    def test_duplicate_preset_error(self):
        # Skip test if using the Python 2 ConfigParser module
        if not hasattr(configparser, 'DuplicateOptionError'):
            return

        parser = PresetParser()

        with self.assertRaises(presets.DuplicatePresetError) as cm:
            parser.read_string(DUPLICATE_PRESET_NAMES)

        e = cm.exception
        self.assertEqual(e.preset_name, 'test')

    def test_get_preset_raw(self):
        parser = PresetParser()
        parser.read_string(INTERPOLATED_PRESET)

        preset = parser.get_preset('test', raw=True)
        self.assertEqual(preset.args, [
            ('--install-symroot', '%(install_symroot)s')
        ])

    def test_get_missing_preset(self):
        parser = PresetParser()

        with self.assertRaises(presets.PresetNotFoundError) as cm:
            parser.get_preset('test')

        e = cm.exception
        self.assertEqual(e.preset_name, 'test')

    def test_preset_names(self):
        parser = PresetParser()

        parser.read_string('[preset: foo]')
        parser.read_string('[preset: bar]')
        parser.read_string('[preset: baz]')

        self.assertEqual(set(parser.preset_names()),
                         set(['foo', 'bar', 'baz']))
