#!/usr/bin/env python

import itertools
import logging
import os
import subprocess
import time

from osx_browser_driver import OSXBrowserDriver
from webkitpy.benchmark_runner.utils import force_remove


_log = logging.getLogger(__name__)


class OSXSafariDriver(OSXBrowserDriver):
    process_name = 'Safari'
    browser_name = 'safari'
    bundle_id = 'com.apple.Safari'

    def prepare_env(self, config):
        self._safari_process = None
        self._safari_preferences = ["-HomePage", "about:blank", "-WarnAboutFraudulentWebsites", "0", "-ExtensionsEnabled", "0", "-ShowStatusBar", "0", "-NewWindowBehavior", "1", "-NewTabBehavior", "1", "-AlwaysRestoreSessionAtLaunch", "0", "-ApplePersistenceIgnoreStateQuietly", "1"]
        super(OSXSafariDriver, self).prepare_env(config)
        self._maximize_window()

    def launch_url(self, url, options, browser_build_path, browser_path):
        args = ['/Applications/Safari.app/Contents/MacOS/Safari']
        env = {}
        if browser_build_path:
            browser_build_absolute_path = os.path.abspath(browser_build_path)
            safari_app_in_build_path = os.path.join(browser_build_absolute_path, 'Safari.app/Contents/MacOS/Safari')
            has_safari_app = os.path.exists(safari_app_in_build_path)
            content_in_path = os.listdir(browser_build_absolute_path)
            contains_frameworks = any(itertools.imap(lambda entry: entry.endswith('.framework'), os.listdir(browser_build_absolute_path)))

            if has_safari_app:
                args = [safari_app_in_build_path]

            if contains_frameworks:
                env = {'DYLD_FRAMEWORK_PATH': browser_build_absolute_path, 'DYLD_LIBRARY_PATH': browser_build_absolute_path,
                    '__XPC_DYLD_FRAMEWORK_PATH': browser_build_absolute_path, '__XPC_DYLD_LIBRARY_PATH': browser_build_absolute_path}
            elif not has_safari_app:
                raise Exception('Could not find any framework "{}"'.format(browser_build_path))

        elif browser_path:
            safari_app_in_browser_path = os.path.join(browser_path, 'Contents/MacOS/Safari')
            if os.path.exists(safari_app_in_browser_path):
                args = [safari_app_in_browser_path]
            else:
                raise Exception('Could not find Safari.app at {}'.format(safari_app_in_browser_path))

        args.extend(self._safari_preferences)
        _log.info('Launching safari: %s with url: %s' % (args[0], url))
        self._safari_process = OSXSafariDriver._launch_process_with_caffeinate(args, env)

        # Stop for initialization of the safari process, otherwise, open
        # command may use the system safari.
        time.sleep(3)

        if browser_build_path:
            _log.info('Checking if any open file is from "{}".'.format(browser_build_path))
            # Cannot use 'check_call' here as '+D' option will have non-zero return code when not all files under
            # specified folder are used.
            process = subprocess.Popen(['/usr/sbin/lsof', '-a', '-p', str(self._safari_process.pid), '+D', browser_build_absolute_path], stdout=subprocess.PIPE)
            output = process.communicate()[0]
            if has_safari_app:
                assert 'Safari.app/Contents/MacOS/Safari' in output, 'Safari.app is not launched from "{}"'.format(browser_build_path)
            if contains_frameworks:
                assert '.framework' in output, 'No framework is loaded from "{}"'.format(browser_build_path)

        subprocess.Popen(['open', '-a', args[0], url])

    def launch_driver(self, url, options, browser_build_path):
        import webkitpy.thirdparty.autoinstalled.selenium
        from selenium import webdriver
        driver = webdriver.Safari(quiet=False)
        self._launch_webdriver(url=url, driver=driver)
        return driver

    def close_browsers(self):
        super(OSXSafariDriver, self).close_browsers()
        if self._safari_process and self._safari_process.returncode:
            sys.exit('Browser crashed with exitcode %d' % self._process.returncode)

    @classmethod
    def _maximize_window(cls):
        try:
            subprocess.check_call(['/usr/bin/defaults', 'write', 'com.apple.Safari', 'NSWindow Frame BrowserWindowFrame', ' '.join(['0', '0', str(cls._screen_size().width), str(cls._screen_size().height)] * 2)])
        except Exception as error:
            _log.error('Reset safari window size failed - Error: {}'.format(error))
