# Write C++ and Python boilerplate code.
#
# Author: Malte J. Ziebarth (malte.ziebarth@tum.de)
#
# Copyright (C) 2025 Technische Universität München
#
# Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
# the European Commission - subsequent versions of the EUPL (the "Licence");
# You may not use this work except in compliance with the Licence.
# You may obtain a copy of the Licence at:
#
# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the Licence is distributed on an "AS IS" basis,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the Licence for the specific language governing permissions and
# limitations under the Licence.
#
# SPDX-FileCopyrightText: 2025 Technical University of Munich
# SPDX-License-Identifier: EUPL-1.2
# SPDX-FileContributor: Malte J. Ziebarth <malte.ziebarth@tum.de>

from typing import Iterable, Literal
from ..wrap.library import WrappedLibrary
from itertools import islice


def generate_boilerplate(
        lib: WrappedLibrary,
        ncols: int,
        language: Literal["C++","Python"]
    ) -> Iterable[str]:
    """
    Generate the license boilerplate code.
    """
    if language == "C++":
        yield f"/*\n"
        indent = " *"
    else:
        indent = "#"
    n_indent = len(indent)
    yield indent
    yield " Autogenerated shared library wrapper for "
    module = ".".join(lib.module())
    if len(module) > ncols - 41 - len(indent):
        # Exceeding maximum column width 'ncols'.
        yield f"\n{indent} {module}\n{indent}\n{indent} Authors: "
    else:
        yield f"{lib.module}\n{indent}\n{indent} Authors: "
    authors = lib.authors()
    if len(authors) == 0:
        raise RuntimeError("No authors declared.")
    yield f"{authors[0][0]} ({authors[0][1]})\n"
    for author, email in islice(authors, 1, None):
        yield f"{indent}          {author} ({email})\n"
    yield from (
        f"{indent}\n{indent} SPDX-FileCopyrightText: {cr}\n"
        for cr in lib.copyright()
    )

    # Assemble the license boilerplate into the column width:
    license_boilerplate = lib.license_boilerplate()
    if license_boilerplate is not None:
        yield f"{indent}\n"
        words = license_boilerplate.split()
        line: list[str] = [indent]
        line_length = n_indent
        for word in words:
            nw = len(word)
            if line_length + nw + 1 > ncols:
                # Start a new line. However, if there's only one long word,
                # write it out here:
                if len(line) == 1:
                    yield f"{indent} {word}\n"
                else:
                    yield " ".join(line)
                    yield "\n"
                    line.clear()
                    line.append(indent)
                    line.append(word)
                    line_length = n_indent + 1 + nw
            else:
                line_length += nw + 1
                line.append(word)

        if len(line) > 1:
            yield " ".join(line)
            yield "\n"

    if language == "C++":
        yield "*/\n"