#!/usr/bin/python3

# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0

import os
import subprocess

from argparse import ArgumentParser, RawTextHelpFormatter
from pathlib import Path
from tempfile import NamedTemporaryFile


DESCRIPTION = """
Usage: generate_ui.py

Generates the source files ui4.cpp, ui4.h used in the uic tool, the QtUiTools library and
Qt Widgets Designer from the XML schema used for .ui files.

Requires xalan.
"""


opt_delete_temp_files = True


def read_cpp_license(path):
    """Read out the license from a C++ source"""
    result = ""
    lines = path.read_text().splitlines()
    for i in range(len(lines)):
        result += lines[i] + "\n"
        if 'Qt-Security' in lines[i]:
            break
        if 'SPDX-License-Identifier' in lines[i] and not 'Qt-Security' in lines[i+1]:
            break
    return result


def replace_xsl_keys(xsl_source_file, license, ui_header_name=None):
    """Replace special keys in XSL files and return a handle to temporary file"""
    xsl = xsl_source_file.read_text()
    xsl = xsl.replace("@LICENSE@", license)
    if ui_header_name:
        xsl = xsl.replace("@HEADER@", ui_header_name)

    result = NamedTemporaryFile(mode='w', suffix='.xsl',
                                dir=Path.cwd(),
                                delete=opt_delete_temp_files)
    result.write(xsl)
    return result


def run_xslt(source, sheet, target):
    """Run xalan."""
    cmd = ['xalan', '-in', os.fspath(source), '-xsl', os.fspath(sheet),
           '-out', os.fspath(target)]
    subprocess.check_call(cmd)


if __name__ == '__main__':
    argument_parser = ArgumentParser(description=DESCRIPTION,
                                     formatter_class=RawTextHelpFormatter)
    argument_parser.add_argument('--keep', '-k', action='store_true',
                                 help='Keep temporary files')
    options = argument_parser.parse_args()
    opt_delete_temp_files = not options.keep

    # Generate uilib header and source.
    xml_dir = Path(__file__).parent.resolve()
    ui4_xsd = xml_dir / 'ui4.xsd'

    designer_dir = xml_dir.parent
    uilib_dir = designer_dir / "src" / "lib" / "uilib"
    uilib_impl = uilib_dir / 'ui4.cpp'
    license = read_cpp_license(uilib_impl)

    print("Running XSLT processor for uilib header...\n")
    header_xsl_source = xml_dir / 'generate_header.xsl'
    header_xsl = replace_xsl_keys(header_xsl_source, license)
    run_xslt(ui4_xsd, header_xsl.name, uilib_dir / 'ui4_p.h')

    print("Running XSLT processor for uilib source...\n")
    impl_xsl_source = xml_dir / 'generate_impl.xsl'
    impl_xsl = replace_xsl_keys(impl_xsl_source, license, 'ui4_p.h')
    run_xslt(ui4_xsd, impl_xsl.name, uilib_impl)

    # uic: Header is called 'ui4.h' instead of 'ui4_p.h'
    uic_dir = designer_dir.parents[2] / "qtbase" / "src" / "tools" / "uic"
    uic_impl = uic_dir / 'ui4.cpp'
    license = read_cpp_license(uic_impl)
    print("Running XSLT processor for uic header...\n")
    header_xsl = replace_xsl_keys(header_xsl_source, license)
    run_xslt(ui4_xsd, header_xsl.name, uic_dir / 'ui4.h')
    print("Running XSLT processor for uic source...\n")
    impl_xsl = replace_xsl_keys(impl_xsl_source, license, 'ui4.h')
    run_xslt(ui4_xsd, impl_xsl.name, uic_impl)

    subprocess.call(['git', 'diff'])
