#!/usr/bin/env python3

###############################################################################/
# Copyright (c) 2021 Nerian Vision GmbH
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
###############################################################################/

#
# This helper script constructs commented Cython .pxd/.pyx source files
#  from their .in templates, utilizing the docstrings generated earlier.
#

import re

from visiontransfer_src.visiontransfer_docstrings_autogen import _NERIAN_COMPILED_DOCSTRINGS

def get_docstring(what):
    if what is None:
        sys.stderr.write('IMPLEMENT_ME: missing docstring link')
        doc = 'IMPLEMENT_ME: missing docstring link'
    elif what in _NERIAN_COMPILED_DOCSTRINGS:
        doc = _NERIAN_COMPILED_DOCSTRINGS[what]
    else:
        doc = '(No extra documentation for ' + what + ')'
        #partial_matches = [k for k in _NERIAN_COMPILED_DOCSTRINGS.keys() if k.startswith(what.split('(')[0])]
        #doc += '\nCandidates:'
        #for p in partial_matches:
        #    doc += '\n  "'+p+'"'
    return doc

def process_infile_to_outfile(infilename, outfilename):
    with open(infilename, 'r') as infile:
        with open(outfilename, 'w') as outfile:
            outfile.write( \
'''# distutils: language=c++
# cython: language_level=3

########################################
## Autogenerated file. Do not change! ##
## Work on its .in template instead   ##
## (found inside visiontransfer_src). ##
########################################

''')
            # looking for docstring substitution sites, the C++ docs are translated
            #  to docstring-like docs, and optionally prepended by a note. The same
            #  indentation that the macro has is used for the entire docstring.
            #  Syntax: _SUBSTITUTE_DOCSTRING_FOR_("CppNamespace::CppClassOrFn"[, "Python note"])
            for line in infile.readlines():
                if line.find('_SUBSTITUTE_DOCSTRING_FOR_(') >= 0:
                    toks = line.split('"')
                    what = toks[1]
                    notelines = [] if len(toks)<4 else ([''] + list(toks[3].split('\n')) + ['']) # extra Python-only note
                    m = re.match(r'([ \t]*)', line)
                    whitespace = m.group(1) if m else ''
                    whitespace_len = len(whitespace)  # common indent
                    clines = get_docstring(what).split('\n')
                    alllines = notelines + clines
                    for i, cl in enumerate(alllines):
                        if i==0:
                            printline = whitespace + ("'''" if i==0 else '') + cl + ("'''" if i==len(alllines)-1 else '')
                        else:
                            printline = cl + ("'''" if i==len(alllines)-1 else '')
                        outfile.write(printline + '\n')
                else:
                    outfile.write(line)

if __name__=='__main__':
    process_infile_to_outfile('visiontransfer_src/visiontransfer.pyx.in',  'visiontransfer/visiontransfer.pyx')
    process_infile_to_outfile('visiontransfer_src/visiontransfer_cpp.pxd.in',  'visiontransfer/visiontransfer_cpp.pxd')
    process_infile_to_outfile('visiontransfer/visiontransfer_parameters_autogen.pyx.in',  'visiontransfer/visiontransfer_parameters_autogen.pyx')

