#!/usr/bin/env python3
import re
import sys

from argparse import ArgumentParser

# This is a very dumb regex based method of translating from
# gn variable declarations and simple if statements to the
# equivalent cmake code. It only supports a few constructs and
# assumes the code is formatted a certain way. ANGLE gn files
# are auto-formatted so this should work most of the time.

# The output may need a bit of manual fixup, but it beats
# translating the whole thing by hand. If new constructs
# are added to the ANGLE gn files, hopefully we can just add
# a few extra regexes here.

parser = ArgumentParser(prog='gni-to-cmake', description='converts a .gni file to .cmake', usage='%(prog)s [options]')
parser.add_argument('gni', help='the .gni file to parse')
parser.add_argument('cmake', help='the .cmake file to output')
parser.add_argument('--prepend', default='', help='the path to prepend to each file name')

args = parser.parse_args()

with open(args.gni, 'r', encoding="utf-8") as gni:
    file = gni.read()

    # Prepend path to every string.
    file = re.sub(r'"((\\\"|[^"])+)"', '"' + args.prepend + r'\1"', file)

    # Remove import, assert, config, and angle_source_set statements.
    file = re.sub(r'^\s*(import|assert|config|angle_source_set)\([^)]+\)( {.*})?$', r'', file, flags=re.MULTILINE|re.DOTALL)

    # Translate gn single line list declaration:
    file = re.sub(r'\[ ((?:"[^"]*",? )*)\]$', r' \1)', file, flags=re.MULTILINE)

    # Translate gn single line list append:
    file = re.sub(r'^(\s*)(\w+) \+= (\w+)$', r'\1 set(\2, "${\2};${\3}")', file, flags=re.MULTILINE)

    # Translate gn list declaration:
    # variable_name = [
    #   "file/name/foo.cpp",
    # ]
    # to cmake list declaration:
    # set(variable_name
    #     "file/name/foo.cpp"
    # )
    file = re.sub(r'^(\s*)(\w+) = ?\[?', r'\1\1set(\2', file, flags=re.MULTILINE)
    file = re.sub(r'^(\s*)("[^"]+"),$', r'\1\1\2', file, flags=re.MULTILINE)
    file = re.sub(r'^(\s*)]$', r'\1\1)', file, flags=re.MULTILINE)

    # Translate list append fom gn to cmake
    file = re.sub(r'^(\s*)(\w+) \+= ?\[?', r'\1\1list(APPEND \2', file, flags=re.MULTILINE)

    # Translate if statements from gn to cmake
    file = re.sub(r'^(\s*)((?:} else )?)if \((.+)\) {$', r'\1\1\2if(\3)', file, flags=re.MULTILINE)
    file = re.sub(r'^} else if$', r'elseif', file, flags=re.MULTILINE)
    file = re.sub(r'^(\s*)} else {$', r'\1\1else()', file, flags=re.MULTILINE)
    file = re.sub(r'^(\s*)}$', r'\1\1endif()', file, flags=re.MULTILINE)

    # Translate logic ops from gn to cmake
    file = re.sub(r' \|\| ', r' OR ', file, flags=re.MULTILINE)
    file = re.sub(r' \&\& ', r' AND ', file, flags=re.MULTILINE)
    file = re.sub(r' == ', r' STREQUAL ', file, flags=re.MULTILINE)
    file = re.sub(r'!', r' NOT ', file, flags=re.MULTILINE)

    with open(args.cmake, 'w', encoding="utf-8") as cmake:
        cmake.write('# This file was generated with the command:\n')
        cmake.write('# ' + ' '.join(['"' + arg.replace('"', '\\"') + '"' for arg in sys.argv]))
        cmake.write('\n\n')
        cmake.write(file)
