#!/usr/bin/env python3
#
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import os
import re
import subprocess

_GN_COMMIT = '4e0818fd86bffc0b4a4b61d3295a6732ba08d715'

_SECTION_RE = re.compile(r'^## <a name="([^"]+)">[^\n]*\n\n(.*?)(?=^## |\Z)', re.DOTALL | re.MULTILINE)
_ITEM_RE = re.compile(r'^### <a name="[^"]+"></a>(\*+([^*]+)\*+[^\n]*?)&nbsp;[^\n]*\n(.*?)(?=^### |\Z)', re.DOTALL | re.MULTILINE)
_VERBATIM_RE = re.compile(r'^```$\n(.*?)^```$', re.DOTALL | re.MULTILINE)


def _ensure_gn(out_dir: str):
    gn_dir = os.path.join(out_dir, 'gn')
    if not os.path.exists(gn_dir):
        subprocess.check_call(['git', 'clone', 'https://gn.googlesource.com/gn'], cwd=out_dir)
    elif subprocess.run(['git', 'cat-file', '-t', _GN_COMMIT], stdout=subprocess.PIPE, cwd=out_dir).stdout.strip() != 'commit':
        subprocess.check_call(['git', 'fetch', 'origin', 'main'], cwd=gn_dir)
    subprocess.check_call(['git', 'checkout', '--quiet', _GN_COMMIT], cwd=gn_dir)


def _generate_builtins(out_dir: str):
    with open(os.path.join(out_dir, 'gn/docs/reference.md')) as f:
        reference = f.read()
    with open(os.path.join(out_dir, 'builtins.gen.rsi'), 'w') as out:
        print('// This file was generated by generate_builtins.py. DO NOT EDIT.', file=out)
        print('', file=out)
        print('BuiltinSymbols {', file=out)
        for m in _SECTION_RE.finditer(reference):
            category = m.group(1)
            if category not in ('targets', 'functions', 'predefined_variables', 'target_variables'):
                continue
            print(f'    {category}: &[', file=out)
            for m in _ITEM_RE.finditer(m.group(2)):
                name = m.group(2)
                doc = m.group(1) + '\n' + m.group(3)
                doc = _VERBATIM_RE.sub(r'```text\n\1```', doc)
                print(f'        BuiltinSymbol {{ name: "{name}", doc: r#"{doc}"# }},', file=out)
            print(f'    ],', file=out)
        print('}', file=out)


def main():
    os.chdir(os.path.dirname(os.path.dirname(__file__)))
    out_dir = os.environ['OUT_DIR']
    _ensure_gn(out_dir)
    _generate_builtins(out_dir)


if __name__ == '__main__':
    main()
