"""Test for qthelp extension."""

from __future__ import annotations

from typing import TYPE_CHECKING

import pytest
from sphinx.testing.util import etree_parse

if TYPE_CHECKING:
    from sphinx.application import Sphinx


@pytest.mark.sphinx('qthelp', testroot='basic')
def test_qthelp_basic(app: Sphinx) -> None:
    app.builder.build_all()

    qhp = (app.outdir / 'Python.qhp').read_text(encoding='utf-8')
    assert '<customFilter name="Python ">' in qhp
    assert '<filterAttribute>Python</filterAttribute>' in qhp
    assert '<filterAttribute></filterAttribute>' in qhp
    assert '<section title="Python  documentation" ref="index.html">' in qhp
    assert '<file>genindex.html</file>' in qhp
    assert '<file>index.html</file>' in qhp
    assert '<file>_static/basic.css</file>' in qhp

    qhcp = (app.outdir / 'Python.qhcp').read_text(encoding='utf-8')
    assert '<title>Python  documentation</title>' in qhcp
    assert '<homePage>qthelp://org.sphinx.python/doc/index.html</homePage>' in qhcp
    assert '<startPage>qthelp://org.sphinx.python/doc/index.html</startPage>' in qhcp
    assert '<input>Python.qhp</input>' in qhcp
    assert '<output>Python.qch</output>' in qhcp
    assert '<file>Python.qch</file>' in qhcp


@pytest.mark.sphinx('qthelp', testroot='need-escaped')
def test_qthelp_escaped(app: Sphinx) -> None:
    app.builder.build_all()

    et = etree_parse(app.outdir / 'needbescapedbproject.qhp')
    customFilter = et.find('.//customFilter')
    assert customFilter is not None
    assert len(customFilter) == 2
    assert customFilter.attrib == {'name': 'need <b>"escaped"</b> project '}
    assert customFilter[0].text == 'needbescapedbproject'
    assert customFilter[1].text is None

    toc = et.find('.//toc')
    assert toc is not None
    assert len(toc) == 1
    assert toc[0].attrib == {'title': 'need <b>"escaped"</b> project  documentation',
                             'ref': 'index.html'}
    assert len(toc[0]) == 4
    assert toc[0][0].attrib == {'title': '<foo>', 'ref': 'foo.html'}
    assert toc[0][0][0].attrib == {'title': 'quux', 'ref': 'quux.html'}
    assert toc[0][0][1].attrib == {'title': 'foo "1"', 'ref': 'foo.html#foo-1'}
    assert toc[0][0][1][0].attrib == {'title': 'foo.1-1', 'ref': 'foo.html#foo-1-1'}
    assert toc[0][0][2].attrib == {'title': 'foo.2', 'ref': 'foo.html#foo-2'}
    assert toc[0][1].attrib == {'title': 'bar', 'ref': 'bar.html'}
    assert toc[0][2].attrib == {'title': 'http://sphinx-doc.org/',
                                'ref': 'http://sphinx-doc.org/'}
    assert toc[0][3].attrib == {'title': 'baz', 'ref': 'baz.html'}

    keywords = et.find('.//keywords')
    assert keywords is not None
    assert len(keywords) == 8
    assert keywords[0].attrib == {'name': '<subsection>',
                                  'ref': 'index.html#index-0'}
    assert keywords[1].attrib == {'name': '& (ampersand)',
                                  'id': 'ampersand.&',
                                  'ref': 'index.html#index-0'}
    assert keywords[2].attrib == {'name': '< (less)',
                                  'id': 'less.<',
                                  'ref': 'index.html#index-0'}
    assert keywords[3].attrib == {'name': '"subsection"',
                                  'ref': 'index.html#index-0'}
    assert keywords[4].attrib == {'name': '> (greater)',
                                  'id': 'greater.>',
                                  'ref': 'index.html#index-0'}
    assert keywords[5].attrib == {'name': 'keyword1 (class in ID)',
                                  'id': 'ID.keyword1',
                                  'ref': 'index.html#index-0'}
    assert keywords[6].attrib == {'name': 'keyword2 (foo bar baz)',
                                  'ref': 'index.html#index-0'}
    assert keywords[7].attrib == {'name': 'Sphinx (document generator)',
                                  'id': 'document.Sphinx',
                                  'ref': 'index.html#index-0'}


@pytest.mark.sphinx('qthelp', testroot='basic')
def test_qthelp_namespace(app: Sphinx) -> None:
    # default namespace
    app.builder.build_all()

    qhp = (app.outdir / 'Python.qhp').read_text(encoding='utf-8')
    assert '<namespace>org.sphinx.python</namespace>' in qhp

    qhcp = (app.outdir / 'Python.qhcp').read_text(encoding='utf-8')
    assert '<homePage>qthelp://org.sphinx.python/doc/index.html</homePage>' in qhcp
    assert '<startPage>qthelp://org.sphinx.python/doc/index.html</startPage>' in qhcp

    # give a namespace
    app.config.qthelp_namespace = 'org.sphinx-doc.sphinx'
    app.builder.build_all()

    qhp = (app.outdir / 'Python.qhp').read_text(encoding='utf-8')
    assert '<namespace>org.sphinx-doc.sphinx</namespace>' in qhp

    qhcp = (app.outdir / 'Python.qhcp').read_text(encoding='utf-8')
    assert '<homePage>qthelp://org.sphinx-doc.sphinx/doc/index.html</homePage>' in qhcp
    assert '<startPage>qthelp://org.sphinx-doc.sphinx/doc/index.html</startPage>' in qhcp


@pytest.mark.sphinx('qthelp', testroot='basic')
def test_qthelp_title(app: Sphinx) -> None:
    # default title
    app.builder.build_all()

    qhp = (app.outdir / 'Python.qhp').read_text(encoding='utf-8')
    assert '<section title="Python  documentation" ref="index.html">' in qhp

    qhcp = (app.outdir / 'Python.qhcp').read_text(encoding='utf-8')
    assert '<title>Python  documentation</title>' in qhcp

    # give a title
    app.config.html_title = 'Sphinx <b>"full"</b> title'
    app.config.html_short_title = 'Sphinx <b>"short"</b> title'
    app.builder.build_all()

    qhp = (app.outdir / 'Python.qhp').read_text(encoding='utf-8')
    assert ('<section title="Sphinx &lt;b&gt;&#34;full&#34;&lt;/b&gt; title" ref="index.html">'
            in qhp)

    qhcp = (app.outdir / 'Python.qhcp').read_text(encoding='utf-8')
    assert '<title>Sphinx &lt;b&gt;&#34;short&#34;&lt;/b&gt; title</title>' in qhcp
