#!/usr/bin/env python3
#
# Re-generate container recipes
#
# This script uses the "lcitool" available from
#
#   https://gitlab.com/libvirt/libvirt-ci
#
# Copyright (c) 2020 Red Hat Inc.
#
# This work is licensed under the terms of the GNU GPL, version 2
# or (at your option) any later version. See the COPYING file in
# the top-level directory.

import sys
import subprocess

from pathlib import Path

if len(sys.argv) != 1:
    print("syntax: %s" % sys.argv[0], file=sys.stderr)
    sys.exit(1)

self_dir = Path(__file__).parent
src_dir = self_dir.parent.parent
dockerfiles_dir = Path(src_dir, "tests", "docker", "dockerfiles")

lcitool_path = Path(self_dir, "libvirt-ci", "bin", "lcitool")

lcitool_cmd = [lcitool_path, "--data-dir", self_dir]


def atomic_write(filename, content):
    tmp = filename.with_suffix(filename.suffix + ".tmp")
    try:
        with tmp.open("w") as fp:
            print(content, file=fp, end="")
            tmp.rename(filename)
    except Exception as ex:
        tmp.unlink()
        raise


def generate(filename, cmd, trailer):
    print("Generate %s" % filename)
    lcitool = subprocess.run(cmd, capture_output=True)

    if lcitool.returncode != 0:
        raise Exception("Failed to generate %s: %s" % (filename, lcitool.stderr))

    content = lcitool.stdout.decode("utf8")
    if trailer is not None:
        content += trailer
    atomic_write(filename, content)

# Optional user setting, this will always be the last thing added
# so maximise the number of layers that are cached
add_user_mapping = [
    "# As a final step configure the user (if env is defined)",
    "ARG USER",
    "ARG UID",
    "RUN if [ \"${USER}\" ]; then \\",
    "  id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi\n"
]

def generate_dockerfile(host, target, cross=None, trailer=None):
    filename = Path(src_dir, "tests", "docker", "dockerfiles", host + ".docker")
    cmd = lcitool_cmd + ["dockerfile"]
    if cross is not None:
        cmd.extend(["--cross", cross])
    cmd.extend([target, "qemu"])

    if trailer is not None:
        trailer += "\n".join(add_user_mapping)
    else:
        trailer = "\n".join(add_user_mapping)

    generate(filename, cmd, trailer)


def generate_cirrus(target, trailer=None):
    filename = Path(src_dir, ".gitlab-ci.d", "cirrus", target + ".vars")
    cmd = lcitool_cmd + ["variables", target, "qemu"]
    generate(filename, cmd, trailer)


# Netmap still needs to be manually built as it is yet to be packaged
# into a distro. We also add cscope and gtags which are used in the CI
# test
debian11_extras = [
    "# netmap/cscope/global\n",
    "RUN DEBIAN_FRONTEND=noninteractive eatmydata \\\n",
    "  apt install -y --no-install-recommends \\\n",
    "  cscope\\\n",
    "  global\\\n",
    "  linux-headers-amd64\n",
    "RUN git clone https://github.com/luigirizzo/netmap.git /usr/src/netmap\n",
    "RUN cd /usr/src/netmap && git checkout v11.3\n",
    "RUN cd /usr/src/netmap/LINUX && ./configure --no-drivers --no-apps --kernel-dir=$(ls -d /usr/src/linux-headers-*-amd64) && make install\n",
    "ENV QEMU_CONFIGURE_OPTS --enable-netmap\n"
]


def cross_build(prefix, targets):
    conf = "ENV QEMU_CONFIGURE_OPTS --cross-prefix=%s\n" % (prefix)
    targets = "ENV DEF_TARGET_LIST %s\n" % (targets)
    return "".join([conf, targets])

#
# Update all the various build configurations.
# Please keep each group sorted alphabetically for easy reading.
#

try:
    #
    # Standard native builds
    #
    generate_dockerfile("alpine", "alpine-316")
    generate_dockerfile("centos8", "centos-stream-8")
    generate_dockerfile("debian-amd64", "debian-11",
                        trailer="".join(debian11_extras))
    generate_dockerfile("fedora", "fedora-37")
    generate_dockerfile("opensuse-leap", "opensuse-leap-15")
    generate_dockerfile("ubuntu2004", "ubuntu-2004")
    generate_dockerfile("ubuntu2204", "ubuntu-2204")

    #
    # Cross compiling builds
    #
    generate_dockerfile("debian-amd64-cross", "debian-11",
                        cross="x86_64",
                        trailer=cross_build("x86_64-linux-gnu-",
                                            "x86_64-softmmu,"
                                            "x86_64-linux-user,"
                                            "i386-softmmu,i386-linux-user"))

    generate_dockerfile("debian-arm64-cross", "debian-11",
                        cross="aarch64",
                        trailer=cross_build("aarch64-linux-gnu-",
                                            "aarch64-softmmu,aarch64-linux-user"))

    generate_dockerfile("debian-armel-cross", "debian-11",
                        cross="armv6l",
                        trailer=cross_build("arm-linux-gnueabi-",
                                            "arm-softmmu,arm-linux-user,armeb-linux-user"))

    generate_dockerfile("debian-armhf-cross", "debian-11",
                        cross="armv7l",
                        trailer=cross_build("arm-linux-gnueabihf-",
                                            "arm-softmmu,arm-linux-user"))

    generate_dockerfile("debian-mips64el-cross", "debian-11",
                        cross="mips64el",
                        trailer=cross_build("mips64el-linux-gnuabi64-",
                                            "mips64el-softmmu,mips64el-linux-user"))

    generate_dockerfile("debian-mipsel-cross", "debian-11",
                        cross="mipsel",
                        trailer=cross_build("mipsel-linux-gnu-",
                                            "mipsel-softmmu,mipsel-linux-user"))

    generate_dockerfile("debian-ppc64el-cross", "debian-11",
                        cross="ppc64le",
                        trailer=cross_build("powerpc64le-linux-gnu-",
                                            "ppc64-softmmu,ppc64-linux-user"))

    generate_dockerfile("debian-s390x-cross", "debian-11",
                        cross="s390x",
                        trailer=cross_build("s390x-linux-gnu-",
                                            "s390x-softmmu,s390x-linux-user"))

    generate_dockerfile("fedora-win32-cross", "fedora-37",
                        cross="mingw32",
                        trailer=cross_build("i686-w64-mingw32-",
                                            "i386-softmmu"))

    generate_dockerfile("fedora-win64-cross", "fedora-37",
                        cross="mingw64",
                        trailer=cross_build("x86_64-w64-mingw32-",
                                            "x86_64-softmmu"))

    #
    # Cirrus packages lists for GitLab
    #
    generate_cirrus("freebsd-13")
    generate_cirrus("macos-12")

    sys.exit(0)
except Exception as ex:
    print(str(ex), file=sys.stderr)
    sys.exit(1)
