# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.

import getpass
import gzip
import os
import os.path
import pytest

import u_boot_utils
from tests import fs_helper

def mkdir_cond(dirname):
    """Create a directory if it doesn't already exist

    Args:
        dirname (str): Name of directory to create
    """
    if not os.path.exists(dirname):
        os.mkdir(dirname)

def setup_image(cons, mmc_dev, part_type):
    """Create a 20MB disk image with a single partition

    Args:
        cons (ConsoleBase): Console to use
        mmc_dev (int): MMC device number to use, e.g. 1
        part_type (int): Partition type, e.g. 0xc for FAT32

    Returns:
        tuple:
            str: Filename of MMC image
            str: Directory name of 'mnt' directory
    """
    fname = os.path.join(cons.config.source_dir, f'mmc{mmc_dev}.img')
    mnt = os.path.join(cons.config.persistent_data_dir, 'mnt')
    mkdir_cond(mnt)

    u_boot_utils.run_and_log(cons, 'qemu-img create %s 20M' % fname)
    u_boot_utils.run_and_log(cons, 'sudo sfdisk %s' % fname,
                             stdin=f'type={part_type:x}'.encode('utf-8'))
    return fname, mnt

def mount_image(cons, fname, mnt, fstype):
    """Create a filesystem and mount it on partition 1

    Args:
        cons (ConsoleBase): Console to use
        fname (str): Filename of MMC image
        mnt (str): Directory name of 'mnt' directory
        fstype (str): Filesystem type ('vfat' or 'ext4')

    Returns:
        str: Name of loop device used
    """
    out = u_boot_utils.run_and_log(cons, 'sudo losetup --show -f -P %s' % fname)
    loop = out.strip()
    part = f'{loop}p1'
    u_boot_utils.run_and_log(cons, f'sudo mkfs.{fstype} {part}')
    opts = ''
    if fstype == 'vfat':
         opts += ' -o uid={os.getuid()},gid={os.getgid()}'
    u_boot_utils.run_and_log(cons, f'sudo mount -o loop {part} {mnt}{opts}')
    u_boot_utils.run_and_log(cons, f'sudo chown {getpass.getuser()} {mnt}')
    return loop

def copy_prepared_image(cons, mmc_dev, fname):
    """Use a prepared image since we cannot create one

    Args:
        cons (ConsoleBase): Console touse
        mmc_dev (int): MMC device number
        fname (str): Filename of MMC image
    """
    infname = os.path.join(cons.config.source_dir,
                           f'test/py/tests/bootstd/mmc{mmc_dev}.img.xz')
    u_boot_utils.run_and_log(
        cons,
        ['sh', '-c', 'xz -dc %s >%s' % (infname, fname)])

def setup_bootmenu_image(cons):
    """Create a 20MB disk image with a single ext4 partition

    This is modelled on Armbian 22.08 Jammy
    """
    mmc_dev = 4
    fname, mnt = setup_image(cons, mmc_dev, 0x83)

    loop = None
    mounted = False
    complete = False
    try:
        loop = mount_image(cons, fname, mnt, 'ext4')
        mounted = True

        vmlinux = 'Image'
        initrd = 'uInitrd'
        dtbdir = 'dtb'
        script = '''# DO NOT EDIT THIS FILE
#
# Please edit /boot/armbianEnv.txt to set supported parameters
#

setenv load_addr "0x9000000"
setenv overlay_error "false"
# default values
setenv rootdev "/dev/mmcblk%dp1"
setenv verbosity "1"
setenv console "both"
setenv bootlogo "false"
setenv rootfstype "ext4"
setenv docker_optimizations "on"
setenv earlycon "off"

echo "Boot script loaded from ${devtype} ${devnum}"

if test -e ${devtype} ${devnum} ${prefix}armbianEnv.txt; then
	load ${devtype} ${devnum} ${load_addr} ${prefix}armbianEnv.txt
	env import -t ${load_addr} ${filesize}
fi

if test "${logo}" = "disabled"; then setenv logo "logo.nologo"; fi

if test "${console}" = "display" || test "${console}" = "both"; then setenv consoleargs "console=tty1"; fi
if test "${console}" = "serial" || test "${console}" = "both"; then setenv consoleargs "console=ttyS2,1500000 ${consoleargs}"; fi
if test "${earlycon}" = "on"; then setenv consoleargs "earlycon ${consoleargs}"; fi
if test "${bootlogo}" = "true"; then setenv consoleargs "bootsplash.bootfile=bootsplash.armbian ${consoleargs}"; fi

# get PARTUUID of first partition on SD/eMMC the boot script was loaded from
if test "${devtype}" = "mmc"; then part uuid mmc ${devnum}:1 partuuid; fi

setenv bootargs "root=${rootdev} rootwait rootfstype=${rootfstype} ${consoleargs} consoleblank=0 loglevel=${verbosity} ubootpart=${partuuid} usb-storage.quirks=${usbstoragequirks} ${extraargs} ${extraboardargs}"

if test "${docker_optimizations}" = "on"; then setenv bootargs "${bootargs} cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory swapaccount=1"; fi

load ${devtype} ${devnum} ${ramdisk_addr_r} ${prefix}uInitrd
load ${devtype} ${devnum} ${kernel_addr_r} ${prefix}Image

load ${devtype} ${devnum} ${fdt_addr_r} ${prefix}dtb/${fdtfile}
fdt addr ${fdt_addr_r}
fdt resize 65536
for overlay_file in ${overlays}; do
	if load ${devtype} ${devnum} ${load_addr} ${prefix}dtb/rockchip/overlay/${overlay_prefix}-${overlay_file}.dtbo; then
		echo "Applying kernel provided DT overlay ${overlay_prefix}-${overlay_file}.dtbo"
		fdt apply ${load_addr} || setenv overlay_error "true"
	fi
done
for overlay_file in ${user_overlays}; do
	if load ${devtype} ${devnum} ${load_addr} ${prefix}overlay-user/${overlay_file}.dtbo; then
		echo "Applying user provided DT overlay ${overlay_file}.dtbo"
		fdt apply ${load_addr} || setenv overlay_error "true"
	fi
done
if test "${overlay_error}" = "true"; then
	echo "Error applying DT overlays, restoring original DT"
	load ${devtype} ${devnum} ${fdt_addr_r} ${prefix}dtb/${fdtfile}
else
	if load ${devtype} ${devnum} ${load_addr} ${prefix}dtb/rockchip/overlay/${overlay_prefix}-fixup.scr; then
		echo "Applying kernel provided DT fixup script (${overlay_prefix}-fixup.scr)"
		source ${load_addr}
	fi
	if test -e ${devtype} ${devnum} ${prefix}fixup.scr; then
		load ${devtype} ${devnum} ${load_addr} ${prefix}fixup.scr
		echo "Applying user provided fixup script (fixup.scr)"
		source ${load_addr}
	fi
fi
booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}

# Recompile with:
# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr
''' % (mmc_dev)
        bootdir = os.path.join(mnt, 'boot')
        mkdir_cond(bootdir)
        cmd_fname = os.path.join(bootdir, 'boot.cmd')
        scr_fname = os.path.join(bootdir, 'boot.scr')
        with open(cmd_fname, 'w') as outf:
            print(script, file=outf)

        infname = os.path.join(cons.config.source_dir,
                               'test/py/tests/bootstd/armbian.bmp.xz')
        bmp_file = os.path.join(bootdir, 'boot.bmp')
        u_boot_utils.run_and_log(
            cons,
            ['sh', '-c', f'xz -dc {infname} >{bmp_file}'])

        u_boot_utils.run_and_log(
            cons, f'mkimage -C none -A arm -T script -d {cmd_fname} {scr_fname}')

        kernel = 'vmlinuz-5.15.63-rockchip64'
        target = os.path.join(bootdir, kernel)
        with open(target, 'wb') as outf:
            print('kernel', outf)

        symlink = os.path.join(bootdir, 'Image')
        if os.path.exists(symlink):
            os.remove(symlink)
        u_boot_utils.run_and_log(
            cons, f'echo here {kernel} {symlink}')
        os.symlink(kernel, symlink)

        u_boot_utils.run_and_log(
            cons, f'mkimage -C none -A arm -T script -d {cmd_fname} {scr_fname}')
        complete = True

    except ValueError as exc:
        print('Falled to create image, failing back to prepared copy: %s',
              str(exc))
    finally:
        if mounted:
            u_boot_utils.run_and_log(cons, 'sudo umount %s' % mnt)
        if loop:
            u_boot_utils.run_and_log(cons, 'sudo losetup -d %s' % loop)

    if not complete:
        copy_prepared_image(cons, mmc_dev, fname)

def setup_bootflow_image(cons):
    """Create a 20MB disk image with a single FAT partition"""
    mmc_dev = 1
    fname, mnt = setup_image(cons, mmc_dev, 0xc)

    loop = None
    mounted = False
    complete = False
    try:
        loop = mount_image(cons, fname, mnt, 'vfat')
        mounted = True

        vmlinux = 'vmlinuz-5.3.7-301.fc31.armv7hl'
        initrd = 'initramfs-5.3.7-301.fc31.armv7hl.img'
        dtbdir = 'dtb-5.3.7-301.fc31.armv7hl'
        script = '''# extlinux.conf generated by appliance-creator
ui menu.c32
menu autoboot Welcome to Fedora-Workstation-armhfp-31-1.9. Automatic boot in # second{,s}. Press a key for options.
menu title Fedora-Workstation-armhfp-31-1.9 Boot Options.
menu hidden
timeout 20
totaltimeout 600

label Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
        kernel /%s
        append ro root=UUID=9732b35b-4cd5-458b-9b91-80f7047e0b8a rhgb quiet LANG=en_US.UTF-8 cma=192MB cma=256MB
        fdtdir /%s/
        initrd /%s''' % (vmlinux, dtbdir, initrd)
        ext = os.path.join(mnt, 'extlinux')
        mkdir_cond(ext)

        with open(os.path.join(ext, 'extlinux.conf'), 'w') as fd:
            print(script, file=fd)

        inf = os.path.join(cons.config.persistent_data_dir, 'inf')
        with open(inf, 'wb') as fd:
            fd.write(gzip.compress(b'vmlinux'))
        u_boot_utils.run_and_log(cons, 'mkimage -f auto -d %s %s' %
                                 (inf, os.path.join(mnt, vmlinux)))

        with open(os.path.join(mnt, initrd), 'w') as fd:
            print('initrd', file=fd)

        mkdir_cond(os.path.join(mnt, dtbdir))

        dtb_file = os.path.join(mnt, '%s/sandbox.dtb' % dtbdir)
        u_boot_utils.run_and_log(
            cons, 'dtc -o %s' % dtb_file, stdin=b'/dts-v1/; / {};')
        complete = True
    except ValueError as exc:
        print('Falled to create image, failing back to prepared copy: %s',
              str(exc))
    finally:
        if mounted:
            u_boot_utils.run_and_log(cons, 'sudo umount %s' % mnt)
        if loop:
            u_boot_utils.run_and_log(cons, 'sudo losetup -d %s' % loop)

    if not complete:
        copy_prepared_image(cons, mmc_dev, fname)


@pytest.mark.buildconfigspec('ut_dm')
def test_ut_dm_init(u_boot_console):
    """Initialize data for ut dm tests."""

    fn = u_boot_console.config.source_dir + '/testflash.bin'
    if not os.path.exists(fn):
        data = b'this is a test'
        data += b'\x00' * ((4 * 1024 * 1024) - len(data))
        with open(fn, 'wb') as fh:
            fh.write(data)

    fn = u_boot_console.config.source_dir + '/spi.bin'
    if not os.path.exists(fn):
        data = b'\x00' * (2 * 1024 * 1024)
        with open(fn, 'wb') as fh:
            fh.write(data)

    # Create a file with a single partition
    fn = u_boot_console.config.source_dir + '/scsi.img'
    if not os.path.exists(fn):
        data = b'\x00' * (2 * 1024 * 1024)
        with open(fn, 'wb') as fh:
            fh.write(data)
        u_boot_utils.run_and_log(
            u_boot_console, f'sfdisk {fn}', stdin=b'type=83')

    fs_helper.mk_fs(u_boot_console.config, 'ext2', 0x200000, '2MB',
                    use_src_dir=True)
    fs_helper.mk_fs(u_boot_console.config, 'fat32', 0x100000, '1MB',
                    use_src_dir=True)

@pytest.mark.buildconfigspec('cmd_bootflow')
def test_ut_dm_init_bootstd(u_boot_console):
    """Initialise data for bootflow tests"""

    setup_bootflow_image(u_boot_console)
    setup_bootmenu_image(u_boot_console)

    # Restart so that the new mmc1.img is picked up
    u_boot_console.restart_uboot()


def test_ut(u_boot_console, ut_subtest):
    """Execute a "ut" subtest.

    The subtests are collected in function generate_ut_subtest() from linker
    generated lists by applying a regular expression to the lines of file
    u-boot.sym. The list entries are created using the C macro UNIT_TEST().

    Strict naming conventions have to be followed to match the regular
    expression. Use UNIT_TEST(foo_test_bar, _flags, foo_test) for a test bar in
    test suite foo that can be executed via command 'ut foo bar' and is
    implemented in C function foo_test_bar().

    Args:
        u_boot_console (ConsoleBase): U-Boot console
        ut_subtest (str): test to be executed via command ut, e.g 'foo bar' to
            execute command 'ut foo bar'
    """

    output = u_boot_console.run_command('ut ' + ut_subtest)
    assert output.endswith('Failures: 0')
