# ===----------------------------------------------------------------------===##
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# ===----------------------------------------------------------------------===##

import os.path
import sys

from libcxx.header_information import module_c_headers, module_headers, header_restrictions, headers_not_available, libcxx_root


def write_file(module):
    with open(libcxx_root / "modules" / f"{module}.cppm.in", "w") as module_cpp_in:
        module_cpp_in.write(
            """\
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// WARNING, this entire header is generated by
// utils/generate_libcxx_cppm_in.py
// DO NOT MODIFY!

module;

#include <__config>

// The headers of Table 24: C++ library headers [tab:headers.cpp]
// and the headers of Table 25: C++ headers for C library facilities [tab:headers.cpp.c]
"""
        )
        for header in sorted(module_headers if module == "std" else module_c_headers):
            if header in header_restrictions:
                module_cpp_in.write(
                    f"""\
#if {header_restrictions[header]}
#  include <{header}>
#endif
"""
                )
            else:
                module_cpp_in.write(f"#include <{header}>\n")

        module_cpp_in.write(
            """
// *** Headers not yet available ***
//
// This validation is mainly to catch when a new header is added but adding the
// corresponding .inc file is forgotten. However, the check based on __has_include
// alone doesn't work on Windows because the Windows SDK is on the include path,
// and that means the MSVC STL headers can be found as well, tricking __has_include
// into thinking that libc++ provides the header.
//
#ifndef _WIN32
"""
        )
        for header in sorted(headers_not_available):
            module_cpp_in.write(
                f"""\
#  if __has_include(<{header}>)
#    error "please update the header information for <{header}> in headers_not_available in utils/libcxx/header_information.py"
#  endif // __has_include(<{header}>)
"""
            )

        module_cpp_in.write(
            f"""#endif // _WIN32

export module {module};
{'export import std;' if module == 'std.compat' else ''}

{'@LIBCXX_MODULE_STD_INCLUDE_SOURCES@' if module == 'std' else ''}
{'@LIBCXX_MODULE_STD_COMPAT_INCLUDE_SOURCES@' if module == 'std.compat' else ''}"""
        )


if __name__ == "__main__":
    if len(sys.argv) != 2 or (sys.argv[1] != "std" and sys.argv[1] != "std.compat"):
        sys.stderr.write(
            f"""\
Usage:
{os.path.basename(__file__)} (std|std.compat)
"""
        )
        sys.exit(1)

    write_file(sys.argv[1])
