# Copyright (c) 2023 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations

import pytest
import logging

from pathlib import Path
from twister_harness import DeviceAdapter, Shell, MCUmgr
from west_sign_wrapper import west_sign_with_imgtool
from utils import (
    find_in_config,
    match_lines,
    match_no_lines,
    check_with_shell_command,
    check_with_mcumgr_command,
)

logger = logging.getLogger(__name__)
PROJECT_NAME = 'with_mcumgr'


def create_signed_image(build_dir: Path, version: str) -> Path:
    image_to_test = Path(build_dir) / 'test_{}.signed.bin'.format(
        version.replace('.', '_').replace('+', '_'))
    origin_key_file = find_in_config(
        Path(build_dir) / 'mcuboot' / 'zephyr' / '.config',
        'CONFIG_BOOT_SIGNATURE_KEY_FILE'
    )
    west_sign_with_imgtool(
        build_dir=Path(build_dir) / PROJECT_NAME,
        output_bin=image_to_test,
        key_file=Path(origin_key_file),
        version=version
    )
    assert image_to_test.is_file()
    return image_to_test


def test_upgrade_with_confirm(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr):
    """
    Verify that the application can be updated
    1) Device flashed with MCUboot and an application that contains SMP server
    2) Prepare an update of an application containing the SMP server
    3) Upload the application update to slot 1 using mcumgr
    4) Flag the application update in slot 1 as 'pending' by using mcumgr 'test'
    5) Restart the device, verify that swapping process is initiated
    6) Verify that the updated application is booted
    7) Confirm the image using mcumgr
    8) Restart the device, and verify that the new application is still booted
    """
    origin_version = find_in_config(
        Path(dut.device_config.build_dir) / PROJECT_NAME / 'zephyr' / '.config',
        'CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION'
    )
    check_with_shell_command(shell, origin_version)

    logger.info('Prepare upgrade image')
    new_version = '0.0.2+0'
    image_to_test = create_signed_image(dut.device_config.build_dir, new_version)

    logger.info('Upload image with mcumgr')
    dut.disconnect()
    mcumgr.image_upload(image_to_test)

    logger.info('Test uploaded APP image')
    second_hash = mcumgr.get_hash_to_test()
    mcumgr.image_test(second_hash)
    mcumgr.reset_device()

    dut.connect()
    output = dut.readlines_until('Launching primary slot application')
    match_lines(output, [
        'Swap type: test',
        'Starting swap using move algorithm'
    ])
    logger.info('Verify new APP is booted')
    check_with_shell_command(shell, new_version, swap_type='test')
    dut.disconnect()
    check_with_mcumgr_command(mcumgr, new_version)

    logger.info('Confirm the image')
    mcumgr.image_confirm(second_hash)
    mcumgr.reset_device()

    dut.connect()
    output = dut.readlines_until('Launching primary slot application')
    match_no_lines(output, [
        'Starting swap using move algorithm'
    ])
    logger.info('Verify new APP is still booted')
    check_with_shell_command(shell, new_version)


def test_upgrade_with_revert(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr):
    """
    Verify that MCUboot will roll back an image that is not confirmed
    1) Device flashed with MCUboot and an application that contains SMP server
    2) Prepare an update of an application containing the SMP server
    3) Upload the application update to slot 1 using mcumgr
    4) Flag the application update in slot 1 as 'pending' by using mcumgr 'test'
    5) Restart the device, verify that swapping process is initiated
    6) Verify that the updated application is booted
    7) Reset the device without confirming the image
    8) Verify that MCUboot reverts update
    """
    origin_version = find_in_config(
        Path(dut.device_config.build_dir) / PROJECT_NAME / 'zephyr' / '.config',
        'CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION'
    )
    check_with_shell_command(shell, origin_version)

    logger.info('Prepare upgrade image')
    new_version = '0.0.3+0'
    image_to_test = create_signed_image(dut.device_config.build_dir, new_version)

    logger.info('Upload image with mcumgr')
    dut.disconnect()
    mcumgr.image_upload(image_to_test)

    logger.info('Test uploaded APP image')
    second_hash = mcumgr.get_hash_to_test()
    mcumgr.image_test(second_hash)
    mcumgr.reset_device()

    dut.connect()
    output = dut.readlines_until('Launching primary slot application')
    match_lines(output, [
        'Swap type: test',
        'Starting swap using move algorithm'
    ])
    logger.info('Verify new APP is booted')
    check_with_shell_command(shell, new_version, swap_type='test')
    dut.disconnect()
    check_with_mcumgr_command(mcumgr, new_version)

    logger.info('Revert images')
    mcumgr.reset_device()

    dut.connect()
    output = dut.readlines_until('Launching primary slot application')
    match_lines(output, [
        'Swap type: revert',
        'Starting swap using move algorithm'
    ])
    logger.info('Verify that MCUboot reverts update')
    check_with_shell_command(shell, origin_version)


@pytest.mark.parametrize(
    'key_file', [None, 'root-ec-p256.pem'],
    ids=[
        'no_key',
        'invalid_key'
    ])
def test_upgrade_signature(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr, key_file):
    """
    Verify that the application is not updated when app is not signed or signed with invalid key
    1) Device flashed with MCUboot and an application that contains SMP server
    2) Prepare an update of an application containing the SMP server that has
       been signed:
       a) without any key
       b) with a different key than MCUboot was compiled with
    3) Upload the application update to slot 1 using mcumgr
    4) Flag the application update in slot 1 as 'pending' by using mcumgr 'test'
    5) Restart the device, verify that swap is not started
    """
    if key_file:
        origin_key_file = find_in_config(
            Path(dut.device_config.build_dir) / 'mcuboot' / 'zephyr' / '.config',
            'CONFIG_BOOT_SIGNATURE_KEY_FILE'
        ).strip('"\'')
        key_file = Path(origin_key_file).parent / key_file
        assert key_file.is_file()
        assert not key_file.samefile(origin_key_file)
        image_to_test = image_to_test = Path(dut.device_config.build_dir) / 'test_invalid_key.bin'
        logger.info('Sign second image with an invalid key')
    else:
        image_to_test = image_to_test = Path(dut.device_config.build_dir) / 'test_no_key.bin'
        logger.info('Sign second imagewith no key')

    west_sign_with_imgtool(
        build_dir=Path(dut.device_config.build_dir) / PROJECT_NAME,
        output_bin=image_to_test,
        key_file=key_file,
        version='0.0.3+4'  # must differ from the origin version, if not then hash is not updated
    )
    assert image_to_test.is_file()

    logger.info('Upload image with mcumgr')
    dut.disconnect()
    mcumgr.image_upload(image_to_test)

    logger.info('Test uploaded APP image')
    second_hash = mcumgr.get_hash_to_test()
    mcumgr.image_test(second_hash)
    mcumgr.reset_device()

    logger.info('Verify that swap is not started')
    dut.connect()
    output = dut.readlines_until('Launching primary slot application')
    match_no_lines(output, ['Starting swap using move algorithm'])
    match_lines(output, ['Image in the secondary slot is not valid'])
