#!/usr/bin/env python
# ===----------------------------------------------------------------------===##
#
# 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
#
# ===----------------------------------------------------------------------===##

# The code is based on
# https://github.com/microsoft/STL/blob/main/tools/unicode_properties_parse/grapheme_break_property_data_gen.py
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

from io import StringIO
from pathlib import Path
from dataclasses import dataclass
from typing import Optional
import re
import sys


@dataclass
class PropertyRange:
    lower: int = -1
    upper: int = -1
    prop: str = None


@dataclass
class Entry:
    lower: int = -1
    offset: int = -1


LINE_REGEX = re.compile(
    r"^(?P<lower>[0-9A-F]{4,6})(?:\.\.(?P<upper>[0-9A-F]{4,6}))?\s*;\s*(?P<prop>\w+)"
)


# https://www.unicode.org/reports/tr44/#GC_Values_Table
def filterGeneralProperty(element: PropertyRange) -> Optional[PropertyRange]:
    if element.prop in ["Zs", "Zl", "Zp", "Cc", "Cf", "Cs", "Co", "Cn"]:
        return element
    return None


def parsePropertyLine(inputLine: str) -> Optional[PropertyRange]:
    result = PropertyRange()
    if m := LINE_REGEX.match(inputLine):
        lower_str, upper_str, result.prop = m.group("lower", "upper", "prop")
        result.lower = int(lower_str, base=16)
        result.upper = result.lower
        if upper_str is not None:
            result.upper = int(upper_str, base=16)
        return result

    else:
        return None


def compactPropertyRanges(input: list[PropertyRange]) -> list[PropertyRange]:
    """
    Merges overlapping and consecutive ranges to one range.

    Since the input properties are filtered the exact property isn't
    interesting anymore. The properties in the output are merged to aid
    debugging.
    Merging the ranges results in fewer ranges in the output table,
    reducing binary and improving lookup performance.
    """
    result = list()
    for x in input:
        if (
            len(result)
            and x.lower > result[-1].lower
            and x.lower <= result[-1].upper + 1
        ):
            result[-1].upper = max(result[-1].upper, x.upper)
            result[-1].prop += f" {x.prop}"
            continue
        result.append(x)
    return result


DATA_ARRAY_TEMPLATE = """
/// The entries of the characters to escape in format's debug string.
///
/// Contains the entries for [format.string.escaped]/2.2.1.2.1
///   CE is a Unicode encoding and C corresponds to a UCS scalar value whose
///   Unicode property General_Category has a value in the groups Separator (Z)
///   or Other (C), as described by table 12 of UAX #44
///
/// Separator (Z) consists of General_Category
/// - Space_Separator,
/// - Line_Separator,
/// - Paragraph_Separator.
///
/// Other (C) consists of General_Category
/// - Control,
/// - Format,
/// - Surrogate,
/// - Private_Use,
/// - Unassigned.
///
/// The data is generated from
/// - https://www.unicode.org/Public/UCD/latest/ucd/extracted/DerivedGeneralCategory.txt
///
/// The table is similar to the table
///  __extended_grapheme_custer_property_boundary::__entries
/// which explains the details of these classes. The only difference is this
/// table lacks a property, thus having more bits available for the size.
///
/// The data has 2 values:
/// - bits [0, 13] The size of the range, allowing 16384 elements.
/// - bits [14, 31] The lower bound code point of the range. The upper bound of
///   the range is lower bound + size. Note the code expects code units the fit
///   into 18 bits, instead of the 21 bits needed for the full Unicode range.
_LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __entries[{size}] = {{
{entries}}};

/// Returns whether the code unit needs to be escaped.
///
/// At the end of the valid Unicode code points space a lot of code points are
/// either reserved or a noncharacter. Adding all these entries to the
/// lookup table would greatly increase the size of the table. Instead these
/// entries are manually processed. In this large area of reserved code points,
/// there is a small area of extended graphemes that should not be escaped
/// unconditionally. This is also manually coded. See the generation script for
/// more details.

///
/// \\pre The code point is a valid Unicode code point.
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool __needs_escape(const char32_t __code_point) noexcept {{

  // The entries in the gap at the end.
  if(__code_point >= 0x{gap_lower:08x} && __code_point <= 0x{gap_upper:08x})
     return false;

  // The entries at the end.
  if (__code_point >= 0x{unallocated:08x})
    return true;

  ptrdiff_t __i = std::ranges::upper_bound(__entries, (__code_point << 14) | 0x3fffu) - __entries;
  if (__i == 0)
    return false;

  --__i;
  uint32_t __upper_bound = (__entries[__i] >> 14) + (__entries[__i] & 0x3fffu);
  return __code_point <= __upper_bound;
}}
"""

TABLES_HPP_TEMPLATE = """
// -*- 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_escaped_output_table.py
// DO NOT MODIFY!

// UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
//
// See Terms of Use <https://www.unicode.org/copyright.html>
// for definitions of Unicode Inc.'s Data Files and Software.
//
// NOTICE TO USER: Carefully read the following legal agreement.
// BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S
// DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"),
// YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
// TERMS AND CONDITIONS OF THIS AGREEMENT.
// IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE
// THE DATA FILES OR SOFTWARE.
//
// COPYRIGHT AND PERMISSION NOTICE
//
// Copyright (c) 1991-2022 Unicode, Inc. All rights reserved.
// Distributed under the Terms of Use in https://www.unicode.org/copyright.html.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of the Unicode data files and any associated documentation
// (the "Data Files") or Unicode software and any associated documentation
// (the "Software") to deal in the Data Files or Software
// without restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, and/or sell copies of
// the Data Files or Software, and to permit persons to whom the Data Files
// or Software are furnished to do so, provided that either
// (a) this copyright and permission notice appear with all copies
// of the Data Files or Software, or
// (b) this copyright and permission notice appear in associated
// Documentation.
//
// THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT OF THIRD PARTY RIGHTS.
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
// NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
// DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THE DATA FILES OR SOFTWARE.
//
// Except as contained in this notice, the name of a copyright holder
// shall not be used in advertising or otherwise to promote the sale,
// use or other dealings in these Data Files or Software without prior
// written authorization of the copyright holder.

#ifndef _LIBCPP___FORMAT_ESCAPED_OUTPUT_TABLE_H
#define _LIBCPP___FORMAT_ESCAPED_OUTPUT_TABLE_H

#include <__algorithm/ranges_upper_bound.h>
#include <__config>
#include <cstddef>
#include <cstdint>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#  pragma GCC system_header
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

#if _LIBCPP_STD_VER >= 23

namespace __escaped_output_table {{
// clang-format off
{content}
// clang-format on
}} // namespace __escaped_output_table

#endif //_LIBCPP_STD_VER >= 23

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___FORMAT_ESCAPED_OUTPUT_TABLE_H"""


def property_ranges_to_table(ranges: list[PropertyRange]) -> list[Entry]:
    result = list[Entry]()
    high = -1
    for range in sorted(ranges, key=lambda x: x.lower):
        # Validate overlapping ranges
        assert range.lower > high
        high = range.upper

        while True:
            e = Entry(range.lower, range.upper - range.lower)
            if e.offset <= 16383:
                result.append(e)
                break
            e.offset = 16383
            result.append(e)
            range.lower += 16384
    return result


cpp_entrytemplate = "    0x{:08x} /* {:08x} - {:08x} [{:>5}] */"


def generate_cpp_data(
    ranges: list[PropertyRange], unallocated: int, gap_lower: int, gap_upper: int
) -> str:
    result = StringIO()
    table = property_ranges_to_table(ranges)
    # Validates all entries fit in 18 bits.
    for x in table:
        assert x.lower + x.offset < 0x3FFFF
    result.write(
        DATA_ARRAY_TEMPLATE.format(
            size=len(table),
            entries=",\n".join(
                [
                    cpp_entrytemplate.format(
                        x.lower << 14 | x.offset,
                        x.lower,
                        x.lower + x.offset,
                        x.offset + 1,
                    )
                    for x in table
                ]
            ),
            unallocated=unallocated,
            gap_lower=gap_lower,
            gap_upper=gap_upper,
        )
    )

    return result.getvalue()


def generate_data_tables() -> str:
    """
    Generate Unicode data for [format.string.escaped]/2.2.1.2.1
    """
    derived_general_catagory_path = (
        Path(__file__).absolute().parent
        / "data"
        / "unicode"
        / "DerivedGeneralCategory.txt"
    )

    properties = list()
    with derived_general_catagory_path.open(encoding="utf-8") as f:
        properties.extend(
            list(
                filter(
                    filterGeneralProperty,
                    [x for line in f if (x := parsePropertyLine(line))],
                )
            )
        )

    data = compactPropertyRanges(sorted(properties, key=lambda x: x.lower))

    # The output table has two large entries at the end, with a small "gap"
    #   E0100..E01EF  ; Grapheme_Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
    # Based on Unicode 15.1.0:
    # - Encoding all these entries in the table requires 1173 entries.
    # - Manually handling these last two blocks reduces the size to 729 entries.
    # This not only reduces the binary size, but also improves the performance
    # by having fewer elements to search.
    # The exact entries may differ between Unicode versions. When these numbers
    # change the test needs to be updated too.
    #   libcxx/test/libcxx/utilities/format/format.string/format.string.std/escaped_output.pass.cpp
    assert (data[-2].lower) == 0x323B0
    assert (data[-2].upper) == 0xE00FF
    assert (data[-1].lower) == 0xE01F0
    assert (data[-1].upper) == 0x10FFFF

    return "\n".join(
        [
            generate_cpp_data(
                data[:-2], data[-2].lower, data[-2].upper + 1, data[-1].lower - 1
            )
        ]
    )


if __name__ == "__main__":
    if len(sys.argv) == 2:
        sys.stdout = open(sys.argv[1], "w")
    print(TABLES_HPP_TEMPLATE.lstrip().format(content=generate_data_tables()))
