# Copyright (C) 2014-2018 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import logging

from webkitpy.common.memoized import memoized
from webkitpy.common.version import Version
from webkitpy.port.config import apple_additions, Config
from webkitpy.port.ios import IOSPort
from webkitpy.xcode.device_type import DeviceType
from webkitpy.xcode.simulated_device import SimulatedDeviceManager


_log = logging.getLogger(__name__)


class IOSSimulatorPort(IOSPort):
    port_name = "ios-simulator"

    FUTURE_VERSION = 'future'
    ARCHITECTURES = ['x86_64', 'i386']
    DEFAULT_ARCHITECTURE = 'x86_64'

    DEVICE_MANAGER = SimulatedDeviceManager

    DEFAULT_DEVICE_TYPES = [
        DeviceType(hardware_family='iPhone', hardware_type='SE'),
        DeviceType(hardware_family='iPad', hardware_type='(5th generation)'),
        DeviceType(hardware_family='iPhone', hardware_type='7'),
    ]
    SDK = apple_additions().get_sdk('iphonesimulator') if apple_additions() else 'iphonesimulator'

    @staticmethod
    def _version_from_name(name):
        if len(name.split('-')) > 2 and name.split('-')[2].isdigit():
            return Version.from_string(name.split('-')[2])
        return None

    @memoized
    def device_version(self):
        if self.get_option('version'):
            return Version.from_string(self.get_option('version'))
        return IOSSimulatorPort._version_from_name(self._name) if IOSSimulatorPort._version_from_name(self._name) else self.host.platform.xcode_sdk_version('iphonesimulator')

    def clean_up_test_run(self):
        super(IOSSimulatorPort, self).clean_up_test_run()
        _log.debug("clean_up_test_run")

        SimulatedDeviceManager.tear_down(self.host)

    def environment_for_api_tests(self):
        no_prefix = super(IOSSimulatorPort, self).environment_for_api_tests()
        result = {}
        SIMCTL_ENV_PREFIX = 'SIMCTL_CHILD_'
        for value in no_prefix:
            if not value.startswith(SIMCTL_ENV_PREFIX):
                result[SIMCTL_ENV_PREFIX + value] = no_prefix[value]
            else:
                result[value] = no_prefix[value]
        return result

    def setup_environ_for_server(self, server_name=None):
        _log.debug("setup_environ_for_server")
        env = super(IOSSimulatorPort, self).setup_environ_for_server(server_name)
        if server_name == self.driver_name():
            if self.get_option('leaks'):
                env['MallocStackLogging'] = '1'
                env['__XPC_MallocStackLogging'] = '1'
                env['MallocScribble'] = '1'
                env['__XPC_MallocScribble'] = '1'
        return env

    def operating_system(self):
        return 'ios-simulator'

    def reset_preferences(self):
        _log.debug("reset_preferences")
        SimulatedDeviceManager.tear_down(self.host)

    def nm_command(self):
        return self.xcrun_find('nm')

    @property
    @memoized
    def developer_dir(self):
        return self._executive.run_command(['xcode-select', '--print-path']).rstrip()

    def logging_patterns_to_strip(self):
        return []

    def stderr_patterns_to_strip(self):
        return []


class IPhoneSimulatorPort(IOSSimulatorPort):
    port_name = 'iphone-simulator'

    DEVICE_TYPE = DeviceType(hardware_family='iPhone')
    DEFAULT_DEVICE_TYPES = [
        DeviceType(hardware_family='iPhone', hardware_type='SE'),
        DeviceType(hardware_family='iPhone', hardware_type='7'),
    ]

    def __init__(self, *args, **kwargs):
        super(IPhoneSimulatorPort, self).__init__(*args, **kwargs)
        self._config = Config(self._executive, self._filesystem, IOSSimulatorPort.port_name)


class IPadSimulatorPort(IOSSimulatorPort):
    port_name = 'ipad-simulator'

    DEVICE_TYPE = DeviceType(hardware_family='iPad')
    DEFAULT_DEVICE_TYPES = [DeviceType(hardware_family='iPad', hardware_type='(5th generation)')]

    def __init__(self, *args, **kwargs):
        super(IPadSimulatorPort, self).__init__(*args, **kwargs)
        self._config = Config(self._executive, self._filesystem, IOSSimulatorPort.port_name)
