#-----------------------------------------------------------------------------
# Copyright (c) 2012 - 2021, Anaconda, Inc., and Bokeh Contributors.
# All rights reserved.
#
# The full license is in the file LICENSE.txt, distributed with this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Boilerplate
#-----------------------------------------------------------------------------
import pytest ; pytest

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

# Standard library imports
import os
import tempfile

# External imports
from mock import patch

# Bokeh imports
from bokeh.document import Document
from bokeh.layouts import row
from bokeh.plotting import figure

# Module under test
import bokeh.command.util as util # isort:skip

#-----------------------------------------------------------------------------
# Setup
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# General API
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Dev API
#-----------------------------------------------------------------------------

def test_die(capsys) -> None:
    with pytest.raises(SystemExit):
        util.die("foo")
    out, err = capsys.readouterr()
    assert err == "foo\n"
    assert out == ""

def test_build_single_handler_application_unknown_file() -> None:
    with pytest.raises(ValueError) as e:
        f = tempfile.NamedTemporaryFile(suffix=".bad")
        util.build_single_handler_application(f.name)
    assert "Expected a '.py' script or '.ipynb' notebook, got: " in str(e.value)

def test_build_single_handler_application_nonexistent_file() -> None:
    with pytest.raises(ValueError) as e:
        util.build_single_handler_application("junkjunkjunk")
    assert "Path for Bokeh server application does not exist: " in str(e.value)

DIRSTYLE_MAIN_WARNING_COPY = """
It looks like you might be running the main.py of a directory app directly.
If this is the case, to enable the features of directory style apps, you must
call "bokeh serve" on the directory instead. For example:

    bokeh serve my_app_dir/

If this is not the case, renaming main.py will suppress this warning.
"""

@patch('warnings.warn')
def test_build_single_handler_application_main_py(mock_warn) -> None:
    f = tempfile.NamedTemporaryFile(suffix="main.py", delete=False)
    f.close() #close file to open it later on windows
    util.build_single_handler_application(f.name)
    assert mock_warn.called
    assert mock_warn.call_args[0] == (DIRSTYLE_MAIN_WARNING_COPY,)
    os.remove(f.name)

_SIZE_WARNING = "Width/height arguments will be ignored for this muliple layout. (Size valus only apply when exporting single plots.)"

class Test_set_single_plot_width_height:
    def test_neither(self) -> None:
        p = figure(plot_width=200, plot_height=300)
        d = Document()
        d.add_root(p)
        util.set_single_plot_width_height(d, None, None)
        assert p.plot_width == 200
        assert p.plot_height == 300

    def test_width(self) -> None:
        p = figure(plot_width=200, plot_height=300)
        d = Document()
        d.add_root(p)
        util.set_single_plot_width_height(d, 400, None)
        assert p.plot_width == 400
        assert p.plot_height == 300

    def test_height(self) -> None:
        p = figure(plot_width=200, plot_height=300)
        d = Document()
        d.add_root(p)
        util.set_single_plot_width_height(d, None, 400)
        assert p.plot_width == 200
        assert p.plot_height == 400

    def test_both(self) -> None:
        p = figure(plot_width=200, plot_height=300)
        d = Document()
        d.add_root(p)
        util.set_single_plot_width_height(d, 400, 500)
        assert p.plot_width == 400
        assert p.plot_height == 500

    def test_multiple_roots(self) -> None:
        p1 = figure(plot_width=200, plot_height=300)
        p2 = figure(plot_width=200, plot_height=300)
        d = Document()
        d.add_root(p1)
        d.add_root(p2)
        with pytest.warns(UserWarning) as warns:
            util.set_single_plot_width_height(d, 400, 500)
            assert len(warns) == 1
            assert warns[0].message.args[0] == _SIZE_WARNING

    def test_layout(self) -> None:
        p = figure(plot_width=200, plot_height=300)
        d = Document()
        d.add_root(row(p))
        with pytest.warns(UserWarning) as warns:
            util.set_single_plot_width_height(d, 400, 500)
            assert len(warns) == 1
            assert warns[0].message.args[0] == _SIZE_WARNING

#-----------------------------------------------------------------------------
# Private API
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Code
#-----------------------------------------------------------------------------
