#!/usr/bin/env python3
# Copyright 2024 The Pigweed Authors
#
# 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
#
#     https://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.
"""Generates macros for encoding tokenizer argument types."""

import datetime
import os

FILE_HEADER = """\
// Copyright {year} The Pigweed Authors
//
// 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
//
//     https://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.

// AUTOGENERATED - DO NOT EDIT
//
// This file was generated by {script}.
// To make changes, update the script and run it to generate new files.
#pragma once

// clang-format off
"""


def _args(count: int) -> str:
    return ','.join(f'a{i}' for i in range(0, count))


def generate_tokenized_enum_macro(max_supported_args: int) -> str:
    """Generates macros to tokenize enums."""

    output = [
        FILE_HEADER.format(
            script=os.path.basename(__file__),
            year=datetime.date.today().year,
        )
    ]

    output.append(''.join('#define _PW_APL0(m,s,n)'))

    for count in range(1, max_supported_args + 1):
        args = [f'\n#define _PW_APL{count}(m,s,n,' f'{_args(count)})']
        enumerator = [f'm({i},n,a{i})s({i},n)' for i in range(0, count - 1)]
        last_enumerator = [f'm({count - 1},n,a{count - 1})']

        output.append(''.join(args))
        output.append(''.join(enumerator))
        output.append(''.join(last_enumerator))

    output.append('\n// clang-format on\n')

    return ''.join(output)


def _main() -> None:
    base_tokenized_enums = os.path.abspath(
        os.path.join(
            os.path.dirname(__file__),
            '..',
            'public',
            'pw_preprocessor',
        )
    )

    with open(
        os.path.join(base_tokenized_enums, 'internal', 'apply_macros.h'),
        'w',
        encoding="utf-8",
    ) as fd:
        fd.write(generate_tokenized_enum_macro(128))

    print('Generated tokenized enum macro headers in', base_tokenized_enums)


if __name__ == '__main__':
    _main()
