#!/usr/bin/env python

import os


def get_libcxx_paths():
    utils_path = os.path.dirname(os.path.abspath(__file__))
    script_name = os.path.basename(__file__)
    assert os.path.exists(utils_path)
    src_root = os.path.dirname(utils_path)
    test_path = os.path.join(src_root, 'test', 'libcxx', 'inclusions')
    assert os.path.exists(test_path)
    assert os.path.exists(os.path.join(test_path, 'algorithm.inclusions.compile.pass.cpp'))
    return script_name, src_root, test_path


script_name, source_root, test_path = get_libcxx_paths()


# This table was produced manually, by grepping the TeX source of the Standard's
# library clauses for the string "#include". Each header's synopsis contains
# explicit "#include" directives for its mandatory inclusions.
# For example, [algorithm.syn] contains "#include <initializer_list>".
#
mandatory_inclusions = {
    "algorithm": ["initializer_list"],
    "array": ["compare", "initializer_list"],
    "bitset": ["iosfwd", "string"],
    "chrono": ["compare"],
    "cinttypes": ["cstdint"],
    "complex.h": ["complex"],
    # TODO "coroutine": ["compare"],
    "deque": ["compare", "initializer_list"],
    "filesystem": ["compare"],
    "forward_list": ["compare", "initializer_list"],
    "ios": ["iosfwd"],
    "iostream": ["ios", "istream", "ostream", "streambuf"],
    "iterator": ["compare", "concepts"],
    "list": ["compare", "initializer_list"],
    "map": ["compare", "initializer_list"],
    "memory": ["compare"],
    "optional": ["compare"],
    "queue": ["compare", "initializer_list"],
    "random": ["initializer_list"],
    "ranges": ["compare", "initializer_list", "iterator"],
    "regex": ["compare", "initializer_list"],
    "set": ["compare", "initializer_list"],
    "stack": ["compare", "initializer_list"],
    "string": ["compare", "initializer_list"],
    "string_view": ["compare"],
    # TODO "syncstream": ["ostream"],
    "system_error": ["compare"],
    "tgmath.h": ["cmath", "complex"],
    "thread": ["compare"],
    "tuple": ["compare"],
    "typeindex": ["compare"],
    "unordered_map": ["compare", "initializer_list"],
    "unordered_set": ["compare", "initializer_list"],
    "utility": ["compare", "initializer_list"],
    "valarray": ["initializer_list"],
    "variant": ["compare"],
    "vector": ["compare", "initializer_list"],
}

new_in_version = {
    "chrono": "11",
    "compare": "20",
    "concepts": "20",
    "coroutine": "20",
    "filesystem": "17",
    "initializer_list": "11",
    "optional": "17",
    "system_error": "11",
    "thread": "11",
    "tuple": "11",
    "unordered_map": "11",
    "unordered_set": "11",
    "string_view": "17",
    "ranges": "20",
    "syncstream": "20",
    "variant": "17",
}

assert all(v == sorted(v) for k, v in mandatory_inclusions.items())

# Map from each header to the Lit annotations that should be used for
# tests that include that header.
#
# For example, when threads are not supported, any test
# that includes <thread> should be marked as UNSUPPORTED, because including
# <thread> is a hard error in that case.
lit_markup = {
  "atomic": ["UNSUPPORTED: libcpp-has-no-threads"],
  "barrier": ["UNSUPPORTED: libcpp-has-no-threads"],
  "filesystem": ["UNSUPPORTED: libcpp-has-no-filesystem-library"],
  "iomanip": ["UNSUPPORTED: libcpp-has-no-localization"],
  "istream": ["UNSUPPORTED: libcpp-has-no-localization"],
  "ios": ["UNSUPPORTED: libcpp-has-no-localization"],
  "iostream": ["UNSUPPORTED: libcpp-has-no-localization"],
  "latch": ["UNSUPPORTED: libcpp-has-no-threads"],
  "locale": ["UNSUPPORTED: libcpp-has-no-localization"],
  "ostream": ["UNSUPPORTED: libcpp-has-no-localization"],
  "regex": ["UNSUPPORTED: libcpp-has-no-localization"],
  "semaphore": ["UNSUPPORTED: libcpp-has-no-threads"],
  "shared_mutex": ["UNSUPPORTED: libcpp-has-no-threads"],
  "thread": ["UNSUPPORTED: libcpp-has-no-threads"],
}


def get_std_ver_test(includee):
    v = new_in_version.get(includee, "03")
    if v == "03":
        return ''
    versions = ["03", "11", "14", "17", "20"]
    return 'TEST_STD_VER > {} && '.format(max(i for i in versions if i < v))


def get_unsupported_line(includee):
    v = new_in_version.get(includee, "03")
    return {
        "03": [],
        "11": ['UNSUPPORTED: c++03'],
        "14": ['UNSUPPORTED: c++03, c++11'],
        "17": ['UNSUPPORTED: c++03, c++11, c++14'],
        "20": ['UNSUPPORTED: c++03, c++11, c++14, c++17'],
        "2b": ['UNSUPPORTED: c++03, c++11, c++14, c++17, c++20'],
    }[v]


def get_libcpp_header_symbol(header_name):
    return '_LIBCPP_' + header_name.upper().replace('.', '_')


def get_includer_symbol_test(includer):
    symbol = get_libcpp_header_symbol(includer)
    return """
#if !defined({symbol})
 #   error "{message}"
#endif
    """.strip().format(
        symbol=symbol,
        message="<{}> was expected to define {}".format(includer, symbol),
    )


def get_ifdef(includer, includee):
    version = max(new_in_version.get(h, "03") for h in [includer, includee])
    symbol = get_libcpp_header_symbol(includee)
    return """
#if {includee_test}!defined({symbol})
 #   error "{message}"
#endif
    """.strip().format(
        includee_test=get_std_ver_test(includee),
        symbol=symbol,
        message="<{}> should include <{}> in C++{} and later".format(includer, includee, version)
    )


test_body_template = """
//===----------------------------------------------------------------------===//
//
// 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 test was generated by {script_name}
// and should not be edited manually.
//
// clang-format off
{markup}
// <{header}>

// Test that <{header}> includes all the other headers it's supposed to.

#include <{header}>
#include "test_macros.h"

{test_includers_symbol}
{test_per_includee}
""".strip()


def produce_tests():
    for includer, includees in mandatory_inclusions.items():
        markup_tags = get_unsupported_line(includer) + lit_markup.get(includer, [])
        test_body = test_body_template.format(
            script_name=script_name,
            header=includer,
            markup=('\n' + '\n'.join('// ' + m for m in markup_tags) + '\n') if markup_tags else '',
            test_includers_symbol=get_includer_symbol_test(includer),
            test_per_includee='\n'.join(get_ifdef(includer, includee) for includee in includees),
        )
        test_name = "{header}.inclusions.compile.pass.cpp".format(header=includer)
        out_path = os.path.join(test_path, test_name)
        with open(out_path, 'w', newline='\n') as f:
            f.write(test_body + '\n')


if __name__ == '__main__':
    produce_tests()
