#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0

import re
import os
import os.path as path
from util import debug

cleanup_on_finish_files = []


def setup(app):
    app.add_event("create_index_softlink")
    app.connect("create_index_softlink", index_softlink)
    app.add_event("toc_from_markdown")
    app.connect("toc_from_markdown", auto_generate_toc)
    app.connect("build-finished", after_build_cleanup)
    return {"version": "1.0", "parallel_read_safe": True}


def after_build_cleanup(app, exception):
    for f in cleanup_on_finish_files:
        os.remove(path.join(app.srcdir, f))
        debug(f"[TOC] Deleted {f}.")


def extract_markdown_links(file):
    """Extracts list of local markdown links from markdown file"""
    # two formats for local markdown file links
    linknameexp1 = r"\[[\/\.\w]*\]"
    linktargetexp1 = r"\(\.[\/\.\w]*{fileext}\)"
    linkexp1 = linknameexp1 + linktargetexp1.format(fileext=r"\.md")

    # case 2 [tag] link
    linknameexp2 = r"\[[0-9]*\]\:\s*"
    linktargetexp2 = r"\.[\/\.\w]*{fileext}\s*\n"
    linkexp2 = linknameexp2 + linktargetexp2.format(fileext=r"\.md")

    links = []
    try:
        with open(file, "r") as f:
            block = f.read()
            for m in re.finditer(linkexp1, block):
                link = m.group(0).partition("(")[2].rpartition(")")[0].strip()
                links.append(link)
            for m in re.finditer(linkexp2, block):
                link = m.group(0).rpartition(":")[2].strip()
                links.append(link)
    except Exception:
        debug(f"[TOC] Warning: Failed to process {file}.")

    return links


def auto_generate_toc(app, master, tocname, cleanup=False, hidden=True, maxdepth=3):
    """
    Automaticaly generate rst file with hidden toc'
    """
    global cleanup_on_finish_files

    if cleanup:
        cleanup_on_finish_files.append(tocname)

    master = path.join(app.srcdir, master)
    tocname = path.join(app.srcdir, path.basename(tocname))
    links = [master]

    while maxdepth:
        newlinks = []
        for file in links:
            fromfile = extract_markdown_links(file)
            newlinks += [
                path.normpath(path.join(os.path.dirname(file), file_link))
                for file_link in fromfile
            ]
        newlinks = [newlink for newlink in set(newlinks) if newlink not in links]
        if not len(newlinks):
            break
        links += newlinks
        maxdepth -= 1

    links = [os.path.relpath(abslink, os.path.dirname(tocname)) for abslink in links]
    links.sort()

    with open(tocname, "w") as f:
        indent = "   "
        f.write(":orphan:\n\n")
        f.write(".. toctree::\n")
        if hidden:
            f.write(indent + ":hidden:\n")
        f.write("\n")
        for link in links:
            f.write(indent + link + "\n")


def index_softlink(app, master, cleanup=False):
    global cleanup_on_finish_files

    softlink = "index." + master.rpartition(".")[2]
    if cleanup:
        cleanup_on_finish_files.append(softlink)

    master = path.join(app.srcdir, master)
    softlink = path.join(app.srcdir, softlink)

    try:
        os.symlink(master, softlink)
    except FileExistsError:
        os.remove(softlink)
        os.symlink(master, softlink)
