#!/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-153")
    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-12")
    generate_cirrus("freebsd-13")
    generate_cirrus("macos-12")

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