#!/usr/bin/env python3

import subprocess
import sys
import os
import argparse
import time


def build(git_repo,
          branch,
          containerfile,
          pkgdirpath):
    timestamp = time.time_ns()
    args = ['podman',
            'build',
            '--pull=always',
            '--force-rm']
    if os.path.exists(git_repo):
        git_repo = os.path.realpath(git_repo)
        args += ['-v',f'{git_repo}:/tmp/mergerfs.git:ro']
        args += ['--build-arg=GIT_REPO=file:///tmp/mergerfs.git']
    else:
        args += [f'--build-arg=GIT_REPO={git_repo}']
    os.makedirs(pkgdirpath,exist_ok=True)
    args += ['-v',f'{os.path.realpath(pkgdirpath)}:/pkgs:ro']
    args += ['-o',pkgdirpath,
             '-f',containerfile,
             f'--build-arg=BRANCH={branch}',
             f'--build-arg=BUILD_TIMESTAMP={timestamp}',
             'buildtools/']
    # TODO: Capture output and write to log
    print(args)
    rv = subprocess.run(args)
    report_filepath = os.path.join(pkgdirpath,"build-report.txt")
    with open(report_filepath,"a+") as f:
        build = os.path.basename(containerfile)
        f.write(build + ": ")
        f.write(f"branch={branch}; ")
        f.write(f"timestamp={timestamp}; ")
        f.write("rv=")
        if rv.returncode == 0:
            f.write("success;")
        else:
            f.write("fail;")
        f.write("\n")


def setup():
    # Detect distribution
    if os.path.exists('/usr/bin/apt-get'):
        args = ['sudo',
                'apt-get',
                'install',
                '-fy',
                'qemu-user-static',
                'qemu-user-binfmt']
    elif os.path.exists('/usr/bin/pacman'):
        args = ['sudo',
                'pacman',
                '-Sy',
                '--noconfirm',
                'qemu-user-static']
    else:
        print("Unsupported distribution for setup")
        sys.exit(1)
    print(args)
    subprocess.run(args)
    setup_binfmt()


def setup_binfmt():
    """Register qemu-user-static binfmt handlers (needed on Arch, etc.)."""
    binfmt_conf = """\
:qemu-aarch64:M::\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xb7\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-aarch64-static:F
:qemu-arm:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-arm-static:F
:qemu-armeb:M::\\x7fELF\\x01\\x02\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff:/usr/bin/qemu-armeb-static:F
:qemu-riscv64:M::\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xf3\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-riscv64-static:F
:qemu-i386:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x03\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-i386-static:F
"""
    conf_path = '/etc/binfmt.d/qemu-static.conf'
    print(f"Writing {conf_path}")
    try:
        with open(conf_path, 'w') as f:
            f.write(binfmt_conf)
    except PermissionError:
        print(f"Permission denied writing {conf_path}; trying with sudo...")
        subprocess.run(['sudo', 'tee', conf_path],
                       input=binfmt_conf.encode(), check=True)

    print("Restarting systemd-binfmt...")
    subprocess.run(['sudo', 'systemctl', 'restart', 'systemd-binfmt'])


def podman_cleanup():
    args = ['podman',
            'system',
            'prune',
            '-af']
    print(args)
    subprocess.run(args)


def parse_args():
    p = argparse.ArgumentParser()
    p.add_argument('--target',
                   default='debian:13.amd64')
    p.add_argument('--pkgdirpath',
                   default='build/pkgs/')
    p.add_argument('--branch',
                   default='master')
    p.add_argument('--setup',
                   required=False,
                   action='store_true')
    p.add_argument('--cleanup',
                   required=False,
                   action='store_true')
    p.add_argument('--git-repo',
                   required=False,
                   type=str)

    return p.parse_args()


def should_skip(filename):
    if filename.endswith('~'):
        return True
    return False


def main():
    args = parse_args()
    print(args)

    if args.setup:
        setup()
        sys.exit(0)

    if not args.git_repo:
        print("error: the following arguments are required: --git-repo")
        sys.exit(1)

    containerfiles = []
    basepath = 'buildtools/containerfiles'
    if os.path.exists(f'{basepath}/{args.target}'):
        containerfiles.append(f'{basepath}/{args.target}')
    elif args.target == 'all':
        for root,dirnames,filenames in os.walk(basepath):
            filenames.sort()
            for filename in filenames:
                if should_skip(filename):
                    continue
                containerfile = f'buildtools/containerfiles/{filename}'
                containerfiles.append(containerfile)
    else:
        for root,dirnames,filenames in os.walk(basepath):
            filenames.sort()
            for filename in filenames:
                if args.target not in filename:
                    continue
                if should_skip(filename):
                    continue
                containerfile = f'buildtools/containerfiles/{filename}'
                containerfiles.append(containerfile)

    for containerfile in containerfiles:
        if args.cleanup:
            podman_cleanup()
        build(git_repo=args.git_repo,
              branch=args.branch,
              containerfile=containerfile,
              pkgdirpath=args.pkgdirpath)

    sys.exit(0)


if __name__ == '__main__':
    main()
