#!/usr/bin/env python3


import re
import shlex
import sys
import typing


RE_FROM_CODE = re.compile(r'^\[\[([^,]+),[^,]*,From Code]]$')
RE_TAG = re.compile('^cmdhelp\\.(.*)$')
RE_SECTION_TITLE = re.compile('^=')
RE_ANCHOR_OR_SECTION_TITLE=re.compile(r'^(?:\[\[.*]]$|=)')

TAG_EXCLUDES = {
    'cmdhelp.root.report',
}


def generate_makefile(stdin, stdout):
    tags = list()
    for line in stdin:
        found = RE_FROM_CODE.match(line)
        if found:
            tag = found.group(1)
            if tag in TAG_EXCLUDES:
                continue
            command = extract_command(tag)
            tags.append(tag)
            stdout.write(tag)
            stdout.write('.txt:\n\t')
            stdout.write(shlex.join(command))
            stdout.write(' > "$@"\n\n')
    end(tags, stdout)


def extract_command(tag: str) -> typing.Sequence[str]:
    found = RE_TAG.match(tag)
    if not found:
        raise RuntimeError(f'Invalid tag {tag}')
    args = ['crm']
    args.extend(found.group(1).split('.', 1))
    args.append('--help-without-redirect')
    return args


def end(tags: typing.Sequence[str], stdout):
    stdout.write(
        '%.adoc: %.txt\n\thelp2adoc "$<" > "$*".adoc\n\n'
    )
    stdout.write(
        '.PHONY: clean all\n\nclean:\n\t$RM *.txt *.adoc\n\nall: '
    )
    for tag in tags:
        stdout.write(tag)
        stdout.write('.adoc ')
    stdout.write('\n\n')


def generate_include(stdin, stdout):
    tag = None
    section_title = None
    for line in stdin:
        go_next_line = False
        while not go_next_line:
            match tag:
                case None:
                    # initial state
                    found = RE_FROM_CODE.match(line)
                    if found:
                        found_tag = found.group(1)
                        if found_tag not in TAG_EXCLUDES:
                            tag = found_tag
                    stdout.write(line)
                    go_next_line = True
                case _:
                    # found a tag
                    match section_title:
                        case None:
                            # waiting a section title
                            found = RE_SECTION_TITLE.match(line)
                            if found:
                                section_title = line
                                stdout.write(section_title)
                                print(f'include::{tag}.adoc[]\n', file=stdout)
                            break
                        case _:
                            # waiting for next section
                            found = RE_ANCHOR_OR_SECTION_TITLE.match(line)
                            if found:
                                tag = None
                                section_title = None
                            else:
                                go_next_line = True


def main():
    if len(sys.argv) != 2:
        print(f'Usage: {sys.argv[0]} gen-makefile|gen-include', file=sys.stderr)
        return 1
    match sys.argv[1]:
        case 'gen-makefile':
            generate_makefile(sys.stdin, sys.stdout)
        case 'gen-include':
            generate_include(sys.stdin, sys.stdout)
    


if __name__ == '__main__':
    sys.exit(main())
