"""
Tests for `chives.javascript`.
"""

from pathlib import Path
import subprocess

import pytest

from chives import __version__, javascript


@pytest.mark.parametrize(
    "contents, expect_error",
    [
        ("", "did not find chives header in file"),
        ("// javascript/chives-example.js\n", "did not find chives header in file"),
        (
            "// javascript/chives-wrongname.js\n// chives version: 1\n",
            "incorrect header",
        ),
        (
            "// javascript/chives-example.js\n// bad version info\n",
            "incorrect header: did not find 'chives version' line",
        ),
    ],
)
def test_malformed_header(tmp_path: Path, contents: str, expect_error: str) -> None:
    """
    The version parser returns meaningful errors.
    """
    (tmp_path / "chives-example.js").write_text(contents)

    with pytest.raises(ValueError, match=expect_error):
        javascript.get_version(tmp_path / "chives-example.js")


git_root_cmd = ["git", "rev-parse", "--show-toplevel"]
GIT_ROOT = subprocess.check_output(git_root_cmd, text=True).strip()
JS_DIR = Path(GIT_ROOT) / "javascript"


class TestUpdateJsComponents:
    """
    Tests for the `chives-update-js` command.
    """

    def test_no_js_files(self, tmp_path: Path) -> None:
        """
        If there are no JS files in the folder, it's a trivial no-op.
        """
        javascript.update_js_components(root=tmp_path, js_assets=JS_DIR)

    def test_updates_matching_js_file(self, tmp_path: Path) -> None:
        """
        If there's a JS file in the folder with a matching filename,
        it's replaced with the current version.
        """
        (tmp_path / "static").mkdir()
        (tmp_path / "static/chives-image.js").write_text("")

        javascript.update_js_components(root=tmp_path, js_assets=JS_DIR)

        assert (
            javascript.get_version(tmp_path / "static/chives-image.js") == __version__
        )

    def test_updates_outdated_js_file(self, tmp_path: Path) -> None:
        """
        If there's a JS file in the folder with a matching filename,
        it's replaced with the current version.
        """
        (tmp_path / "static").mkdir()
        (tmp_path / "static/chives-image.js").write_text(
            "// javascript/chives-image.js\n// chives version: 1\n"
        )

        javascript.update_js_components(root=tmp_path, js_assets=JS_DIR)

        assert (
            javascript.get_version(tmp_path / "static/chives-image.js") == __version__
        )

    def test_ignores_unmatched_js_file(self, tmp_path: Path) -> None:
        """
        If there's a JS file that doesn't come from chives, it's left as-is.
        """
        js = "function greet() { console.log('Hello world!'); }"
        (tmp_path / "chives-example.js").write_text(js)

        javascript.update_js_components(root=tmp_path, js_assets=JS_DIR)

        assert (tmp_path / "chives-example.js").read_text() == js

    def test_ignores_already_up_to_date_file(self, tmp_path: Path) -> None:
        """
        Once a JS file is up-to-date, it's not edited again.
        """
        (tmp_path / "static").mkdir()
        (tmp_path / "static/chives-image.js").write_text("")

        javascript.update_js_components(root=tmp_path, js_assets=JS_DIR)
        mtime = (tmp_path / "static/chives-image.js").stat().st_mtime

        javascript.update_js_components(root=tmp_path, js_assets=JS_DIR)
        assert (tmp_path / "static/chives-image.js").stat().st_mtime == mtime
