from __future__ import annotations

from pygitweb.static_tests.js_runtime import JsPage


def _blob(js: JsPage, code: str, lines: str | None) -> None:
	href = "http://127.0.0.1/blob"
	if lines is not None:
		href += "?lines=" + lines
	js.set_location(href)
	js.set_html(f'<pre class="blob-content"><code>{code}</code></pre>')


def test_missing_code_element_is_ignored(js: JsPage) -> None:
	js.set_location("http://127.0.0.1/blob?lines=L1")
	js.set_html("<div></div>")
	js.load("blob-view.js")
	assert js.count("[data-line]") == 0


def test_no_lines_param_leaves_the_code_unwrapped(js: JsPage) -> None:
	js.run("globalThis.hljs = { highlightElement: function(code) { code.setAttribute('data-hl', '1'); } };")
	_blob(js, "print('hi')", None)
	js.load("blob-view.js")
	assert js.attr(".blob-content code", "data-hl") == "1"
	assert js.count("[data-line]") == 0


def test_a_full_line_range_selects_each_line_and_scrolls(js: JsPage) -> None:
	_blob(js, "alpha\nbeta\ngamma", "L1-L2")
	js.load("blob-view.js")
	assert "blob-line-selected" in js.classes('[data-line="1"]')
	assert "blob-line-selected" in js.classes('[data-line="2"]')
	assert "blob-line-selected" not in js.classes('[data-line="3"]')
	assert js.value("__lastScrolled && __lastScrolled.tagName") == "SPAN"


def test_a_character_range_wraps_a_selection_span(js: JsPage) -> None:
	_blob(js, "print('hi')", "L1C2-L1C5")
	js.load("blob-view.js")
	assert js.text(".blob-selection") == "rint"
	assert js.count(".blob-line-selected") == 0


def test_a_zero_width_range_does_not_wrap(js: JsPage) -> None:
	_blob(js, "print('hi')", "L1C5-L1C4")
	js.load("blob-view.js")
	assert js.count(".blob-selection") == 0
	assert js.count(".blob-line-selected") == 0


def test_a_missing_line_is_skipped(js: JsPage) -> None:
	_blob(js, "only", "L9")
	js.load("blob-view.js")
	assert js.count(".blob-line-selected") == 0
	assert js.value("__lastScrolled") is None


def test_highlight_elements_are_kept_inside_line_spans(js: JsPage) -> None:
	js.run(
		"globalThis.hljs = { highlightElement: function(code) {"
		" var text = code.textContent; code.textContent = '';"
		" var span = document.createElement('span'); span.className = 'hljs-built_in';"
		" span.textContent = text; code.appendChild(span); } };"
	)
	_blob(js, "print('hi')", "L1")
	js.load("blob-view.js")
	assert js.count('[data-line="1"] .hljs-built_in') == 1
	assert "blob-line-selected" in js.classes('[data-line="1"]')


def test_a_range_across_nodes_is_ignored_when_surround_fails(js: JsPage) -> None:
	_blob(js, "ab<span>XX</span>cd", "L1C1-L1C6")
	js.load("blob-view.js")
	assert js.count(".blob-selection") == 0
	assert js.count("[data-line]") == 1


def test_several_ranges_in_one_param_are_applied(js: JsPage) -> None:
	_blob(js, "one\ntwo", "L1,L2C1-L2C2")
	js.load("blob-view.js")
	assert "blob-line-selected" in js.classes('[data-line="1"]')
	assert js.text(".blob-selection") == "tw"