
# -*- coding: utf-8 -*-
"""
This module is meant to run JupyterLab in a headless browser, making sure
the application launches and starts up without errors.
"""
from concurrent.futures import ThreadPoolExecutor
import logging
from os import path as osp
import os
import shutil
import sys
import subprocess

from tornado.ioloop import IOLoop
from jupyter_server.serverapp import flags, aliases, ServerApp
from jupyter_server.utils import urljoin, pathname2url
from traitlets import Bool, Dict

from .labapp import LabApp, get_app_dir
from .tests.test_app import TestEnv


here = osp.abspath(osp.dirname(__file__))
test_flags = dict(flags)
test_flags['core-mode'] = (
    {'BrowserApp': {'core_mode': True}},
    "Start the app in core mode."
)
test_flags['dev-mode'] = (
    {'BrowserApp': {'dev_mode': True}},
    "Start the app in dev mode."
)


test_aliases = dict(aliases)
test_aliases['app-dir'] = 'BrowserApp.app_dir'


class LogErrorHandler(logging.Handler):
    """A handler that exits with 1 on a logged error."""

    def __init__(self):
        super().__init__(level=logging.ERROR)
        self.errored = False

    def filter(self, record):
        # known startup error message
        if 'paste' in record.msg:
            return
        # handle known shutdown message
        if 'Stream is closed' in record.msg:
            return
        return super().filter(record)

    def emit(self, record):
        print(record.msg, file=sys.stderr)
        self.errored = True


def run_test(app, func):
    """Run a test against the application.
    func is a function that accepts an app url as a parameter and returns a result.
    """
    handler = LogErrorHandler()

    env_patch = TestEnv()
    env_patch.start()

    def finished(future):
        try:
            result = future.result()
        except Exception as e:
            app.log.error(str(e))
        app.log.info('Stopping server...')
        app.stop()
        if handler.errored:
            app.log.critical('Exiting with 1 due to errors')
            result = 1
        elif result != 0:
            app.log.critical('Exiting with %s due to errors' % result)
        else:
            app.log.info('Exiting normally')
            result = 0

        try:
            app.http_server.stop()
            app.io_loop.stop()
            env_patch.stop()
            os._exit(result)
        except Exception as e:
            self.log.error(str(e))
            if 'Stream is closed' in str(e):
                os._exit(result)
            os._exit(1)

    # The entry URL for browser tests is different in notebook >= 6.0,
    # since that uses a local HTML file to point the user at the app.
    if hasattr(app, 'browser_open_file'):        
        url = urljoin('file:', pathname2url(app.browser_open_file))
    else:
        url = app.display_url

    app.log.addHandler(handler)
    pool = ThreadPoolExecutor()
    future = pool.submit(func, url)
    IOLoop.current().add_future(future, finished)


def run_browser(url):
    """Run the browser test and return an exit code.
    """
    target = osp.join(get_app_dir(), 'browser_test')
    if not osp.exists(osp.join(target, 'node_modules')):
        os.makedirs(target)
        subprocess.call(["jlpm", "init", "-y"], cwd=target)
        subprocess.call(["jlpm", "add", "puppeteer"], cwd=target)
    shutil.copy(osp.join(here, 'chrome-test.js'), osp.join(target, 'chrome-test.js'))
    return subprocess.check_call(["node", "chrome-test.js", url], cwd=target)


class BrowserApp(LabApp):
    """An app the launches JupyterLab and waits for it to start up, checking for
    JS console errors, JS errors, and Python logged errors.
    """
    extension_name = __name__
    open_browser = Bool(False)
    ip = '127.0.0.1'
    flags = test_flags
    aliases = test_aliases
    test_browser = Bool(True)

    def initialize_settings(self):
        self.settings.setdefault('page_config_data', dict())
        self.settings['page_config_data']['browserTest'] = True
        self.settings['page_config_data']['buildAvailable'] = False
        self.serverapp.base_url = '/lab'
        super().initialize_settings()

    def initialize_handlers(self):
        func = run_browser if self.test_browser else lambda url: 0
        run_test(self, func)
        super().initialize_handlers()

        web_app.settings.setdefault('page_config_data', dict())
        web_app.settings['page_config_data']['browserTest'] = True
        web_app.settings['page_config_data']['buildAvailable'] = False
        super().start()

if __name__ == '__main__':
    skip_option = "--no-chrome-test"
    if skip_option in sys.argv:
        BrowserApp.test_browser = False
        sys.argv.remove(skip_option)
    def _jupyter_server_extension_paths():
        return [
            {
                'module': __name__,
                'app': BrowserApp
            }
        ]
    sys.modules[__name__]._jupyter_server_extension_paths = _jupyter_server_extension_paths
    ServerApp.jpserver_extensions = Dict({__name__: True})
    ServerApp.launch_instance()

@@ -3820,18 +3820,12 @@
 r = 
-Bool(
 True
-)
 %0A%0A  
@@ -4054,49 +4054,8 @@
 lse%0A
-        self.serverapp.base_url = '/lab'%0A
     
@@ -4212,16 +4212,26 @@
 est(self
+.serverapp
 , func)%0A
@@ -4273,235 +4273,8 @@
 ()%0A%0A
-        web_app.settings.setdefault('page_config_data', dict())%0A        web_app.settings%5B'page_config_data'%5D%5B'browserTest'%5D = True%0A        web_app.settings%5B'page_config_data'%5D%5B'buildAvailable'%5D = False%0A        super().start()%0A%0A
 if _
@@ -4710,71 +4710,13 @@
     
-ServerApp.jpserver_extensions = Dict(%7B__name__: True%7D)%0A    Serv
+Brows
 erAp

fix browser check