#!/usr/bin/env python

import unittest
from frodocs.structure.toc import get_toc
from frodocs.tests.base import dedent, get_markdown_toc


class TableOfContentsTests(unittest.TestCase):

    def test_indented_toc(self):
        md = dedent("""
        # Heading 1
        ## Heading 2
        ### Heading 3
        """)
        expected = dedent("""
        Heading 1 - #heading-1
            Heading 2 - #heading-2
                Heading 3 - #heading-3
        """)
        toc = get_toc(get_markdown_toc(md))
        self.assertEqual(str(toc).strip(), expected)
        self.assertEqual(len(toc), 1)

    def test_indented_toc_html(self):
        md = dedent("""
        # Heading 1
        ## <code>Heading</code> 2
        ## Heading 3
        """)
        expected = dedent("""
        Heading 1 - #heading-1
            Heading 2 - #heading-2
            Heading 3 - #heading-3
        """)
        toc = get_toc(get_markdown_toc(md))
        self.assertEqual(str(toc).strip(), expected)
        self.assertEqual(len(toc), 1)

    def test_flat_toc(self):
        md = dedent("""
        # Heading 1
        # Heading 2
        # Heading 3
        """)
        expected = dedent("""
        Heading 1 - #heading-1
        Heading 2 - #heading-2
        Heading 3 - #heading-3
        """)
        toc = get_toc(get_markdown_toc(md))
        self.assertEqual(str(toc).strip(), expected)
        self.assertEqual(len(toc), 3)

    def test_flat_h2_toc(self):
        md = dedent("""
        ## Heading 1
        ## Heading 2
        ## Heading 3
        """)
        expected = dedent("""
        Heading 1 - #heading-1
        Heading 2 - #heading-2
        Heading 3 - #heading-3
        """)
        toc = get_toc(get_markdown_toc(md))
        self.assertEqual(str(toc).strip(), expected)
        self.assertEqual(len(toc), 3)

    def test_mixed_toc(self):
        md = dedent("""
        # Heading 1
        ## Heading 2
        # Heading 3
        ### Heading 4
        ### Heading 5
        """)
        expected = dedent("""
        Heading 1 - #heading-1
            Heading 2 - #heading-2
        Heading 3 - #heading-3
            Heading 4 - #heading-4
            Heading 5 - #heading-5
        """)
        toc = get_toc(get_markdown_toc(md))
        self.assertEqual(str(toc).strip(), expected)
        self.assertEqual(len(toc), 2)

    def test_mixed_html(self):
        md = dedent("""
        # Heading 1
        ## Heading 2
        # Heading 3
        ### Heading 4
        ### <a>Heading 5</a>
        """)
        expected = dedent("""
        Heading 1 - #heading-1
            Heading 2 - #heading-2
        Heading 3 - #heading-3
            Heading 4 - #heading-4
            Heading 5 - #heading-5
        """)
        toc = get_toc(get_markdown_toc(md))
        self.assertEqual(str(toc).strip(), expected)
        self.assertEqual(len(toc), 2)

    def test_nested_anchor(self):
        md = dedent("""
        # Heading 1
        ## Heading 2
        # Heading 3
        ### Heading 4
        ### <a href="/">Heading 5</a>
        """)
        expected = dedent("""
        Heading 1 - #heading-1
            Heading 2 - #heading-2
        Heading 3 - #heading-3
            Heading 4 - #heading-4
            Heading 5 - #heading-5
        """)
        toc = get_toc(get_markdown_toc(md))
        self.assertEqual(str(toc).strip(), expected)
        self.assertEqual(len(toc), 2)

    def test_entityref(self):
        md = dedent("""
        # Heading & 1
        ## Heading > 2
        ### Heading < 3
        """)
        expected = dedent("""
        Heading &amp; 1 - #heading-1
            Heading &gt; 2 - #heading-2
                Heading &lt; 3 - #heading-3
        """)
        toc = get_toc(get_markdown_toc(md))
        self.assertEqual(str(toc).strip(), expected)
        self.assertEqual(len(toc), 1)

    def test_charref(self):
        md = '# &#64;Header'
        expected = '&#64;Header - #header'
        toc = get_toc(get_markdown_toc(md))
        self.assertEqual(str(toc).strip(), expected)
        self.assertEqual(len(toc), 1)

    def test_level(self):
        md = dedent("""
        # Heading 1
        ## Heading 1.1
        ### Heading 1.1.1
        ### Heading 1.1.2
        ## Heading 1.2
        """)
        toc = get_toc(get_markdown_toc(md))

        def get_level_sequence(items):
            for item in items:
                yield item.level
                yield from get_level_sequence(item.children)

        self.assertEqual(tuple(get_level_sequence(toc)), (1, 2, 3, 3, 2))
