#!/usr/bin/env python
r"""Emulates the bits of CMake's configure_file() function needed in LLVM.

The CMake build uses configure_file() for several things.  This emulates that
function for the GN build.  In the GN build, this runs at build time instead
of at generator time.

Takes a list of KEY=VALUE pairs (where VALUE can be empty).

The sequence `\` `n` in each VALUE is replaced by a newline character.

On each line, replaces '${KEY}' or '@KEY@' with VALUE.

Then, handles these special cases (note that FOO= sets the value of FOO to the
empty string, which is falsy, but FOO=0 sets it to '0' which is truthy):

1.) #cmakedefine01 FOO
    Checks if key FOO is set to a truthy value, and depending on that prints
    one of the following two lines:

        #define FOO 1
        #define FOO 0

2.) #cmakedefine FOO [...]
    Checks if key FOO is set to a truthy in value, and depending on that prints
    one of the following two lines:

        #define FOO [...]
        /* #undef FOO */

Fails if any of the KEY=VALUE arguments aren't needed for processing the
input file, or if the input file references keys that weren't passed in.
"""

from __future__ import print_function

import argparse
import os
import re
import sys


def main():
    parser = argparse.ArgumentParser(
                 epilog=__doc__,
                 formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('input', help='input file')
    parser.add_argument('values', nargs='*', help='several KEY=VALUE pairs')
    parser.add_argument('-o', '--output', required=True,
                        help='output file')
    args = parser.parse_args()

    values = {}
    for value in args.values:
        key, val = value.split('=', 1)
        if key in values:
            print('duplicate key "%s" in args' % key, file=sys.stderr)
            return 1
        values[key] = val.replace('\\n', '\n')
    unused_values = set(values.keys())

    # Matches e.g. '${FOO}' or '@FOO@' and captures FOO in group 1 or 2.
    var_re = re.compile(r'\$\{([^}]*)\}|@([^@]*)@')

    with open(args.input) as f:
        in_lines = f.readlines()
    out_lines = []
    for in_line in in_lines:
        def repl(m):
            key = m.group(1) or m.group(2)
            unused_values.discard(key)
            return values[key]
        in_line = var_re.sub(repl, in_line)
        if in_line.startswith('#cmakedefine01 '):
            _, var = in_line.split()
            in_line = '#define %s %d\n' % (var, 1 if values[var] else 0)
            unused_values.discard(var)
        elif in_line.startswith('#cmakedefine '):
            _, var = in_line.split(None, 1)
            try:
                var, val = var.split(None, 1)
                in_line = '#define %s %s' % (var, val)  # val ends in \n.
            except:
                var = var.rstrip()
                in_line = '#define %s\n' % var
            if not values[var]:
                in_line = '/* #undef %s */\n' % var
            unused_values.discard(var)
        out_lines.append(in_line)

    if unused_values:
        print('unused values args:', file=sys.stderr)
        print('    ' + '\n    '.join(unused_values), file=sys.stderr)
        return 1

    output = ''.join(out_lines)

    leftovers = var_re.findall(output)
    if leftovers:
        print(
            'unprocessed values:\n',
            '\n'.join([x[0] or x[1] for x in leftovers]),
            file=sys.stderr)
        return 1

    def read(filename):
        with open(args.output) as f:
            return f.read()

    if not os.path.exists(args.output) or read(args.output) != output:
        with open(args.output, 'w') as f:
            f.write(output)
        os.chmod(args.output, os.stat(args.input).st_mode & 0o777)


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