#!/usr/bin/env python3
# A tool to parse the output of `clang-format --help` and update the
# documentation in ../ClangFormat.rst automatically.

import os
import re
import subprocess
import sys

CLANG_DIR = os.path.join(os.path.dirname(__file__), '../..')
DOC_FILE = os.path.join(CLANG_DIR, 'docs/ClangFormat.rst')


def substitute(text, tag, contents):
    replacement = '\n.. START_%s\n\n%s\n\n.. END_%s\n' % (tag, contents, tag)
    pattern = r'\n\.\. START_%s\n.*\n\.\. END_%s\n' % (tag, tag)
    return re.sub(pattern, '%s', text, flags=re.S) % replacement


def indent(text, columns, indent_first_line=True):
    indent_str = ' ' * columns
    s = re.sub(r'\n([^\n])', '\n' + indent_str + '\\1', text, flags=re.S)
    if not indent_first_line or s.startswith('\n'):
        return s
    return indent_str + s


def get_help_output():
    args = ["clang-format", "--help"]
    cmd = subprocess.Popen(args, stdout=subprocess.PIPE,
                           stderr=subprocess.STDOUT)
    out, _ = cmd.communicate()
    out = out.decode(sys.stdout.encoding)
    return out


def get_help_text():
    out = get_help_output()
    out = re.sub(r' clang-format\.exe ', ' clang-format ', out)

    out = '''.. code-block:: console

$ clang-format -help
''' + out
    out = indent(out, 2, indent_first_line=False)
    return out


def validate(text, columns):
    for line in text.splitlines():
        if len(line) > columns:
            print('warning: line too long:\n', line, file=sys.stderr)


help_text = get_help_text()
validate(help_text, 95)

with open(DOC_FILE) as f:
    contents = f.read()

contents = substitute(contents, 'FORMAT_HELP', help_text)

with open(DOC_FILE, 'wb') as output:
    output.write(contents.encode())
