# SPDX-License-Identifier: GPL-2.0
# (C) Copyright 2024, Advanced Micro Devices, Inc.

"""
Note: This test relies on boardenv_* containing configuration values to define
spi minimum and maximum frequencies at which the flash part can operate on and
these tests run at different spi frequency randomised values in the range
multiple times based on the user defined iteration value.
It also defines the SPI bus number containing the SPI-flash chip, SPI
chip-select, SPI mode, SPI flash part name and timeout parameters. If minimum
and maximum frequency is not defined, it will run on freq 0 by default.

Without the boardenv_* configuration, this test will be automatically skipped.

It also relies on configuration values for supported flashes for lock and
unlock cases for SPI family flash. It will run lock-unlock cases only for the
supported flash parts.

For Example:

# Details of SPI device test parameters required for SPI device testing:

# bus - SPI bus number to init the flash device
# chip_select - SPI chip select number to init the flash device
# min_freq - Minimum frequency in hz at which the flash part can operate, set 0
# or None for default frequency
# max_freq - Maximum frequency in hz at which the flash part can operate, set 0
# or None for default frequency
# mode - SPI mode to init the flash device
# part_name - SPI flash part name to be detected
# timeout - Default timeout to run the sf commands
# iteration - No of iteration to run SPI flash test

env__spi_device_test = {
    'bus': 0,
    'chip_select': 0,
    'min_freq': 10000000,
    'max_freq': 100000000,
    'mode': 0,
    'part_name': 'n25q00a',
    'timeout': 100000,
    'iteration': 5,
}

# supported_flash - Flash parts name which support lock-unlock functionality
env__spi_lock_unlock = {
    'supported_flash': 'mt25qu512a, n25q00a, n25q512ax3',
}
"""

import random
import re
import pytest
import u_boot_utils

SPI_DATA = {}
EXPECTED_ERASE = 'Erased: OK'
EXPECTED_WRITE = 'Written: OK'
EXPECTED_READ = 'Read: OK'
EXPECTED_ERASE_ERRORS = [
    'Erase operation failed',
    'Attempted to modify a protected sector',
    'Erased: ERROR',
    'is protected and cannot be erased',
    'ERROR: flash area is locked',
]
EXPECTED_WRITE_ERRORS = [
    'ERROR: flash area is locked',
    'Program operation failed',
    'Attempted to modify a protected sector',
    'Written: ERROR',
]

def get_params_spi(u_boot_console):
    ''' Get SPI device test parameters from boardenv file '''
    f = u_boot_console.config.env.get('env__spi_device_test', None)
    if not f:
        pytest.skip('No env file to read for SPI family device test')

    bus = f.get('bus', 0)
    cs = f.get('chip_select', 0)
    mode = f.get('mode', 0)
    part_name = f.get('part_name', None)
    timeout = f.get('timeout', None)

    if not part_name:
        pytest.skip('No env file to read SPI family flash part name')

    return bus, cs, mode, part_name, timeout

def spi_find_freq_range(u_boot_console):
    '''Find out minimum and maximum frequnecies that SPI device can operate'''
    f = u_boot_console.config.env.get('env__spi_device_test', None)
    if not f:
        pytest.skip('No env file to read for SPI family device test')

    min_f = f.get('min_freq', None)
    max_f = f.get('max_freq', None)
    iterations = f.get('iteration', 1)

    if not min_f:
        min_f = 0
    if not max_f:
        max_f = 0

    max_f = max(max_f, min_f)

    return min_f, max_f, iterations

def spi_pre_commands(u_boot_console, freq):
    ''' Find out SPI family flash memory parameters '''
    bus, cs, mode, part_name, timeout = get_params_spi(u_boot_console)

    output = u_boot_console.run_command(f'sf probe {bus}:{cs} {freq} {mode}')
    if not 'SF: Detected' in output:
        pytest.fail('No SPI device available')

    if not part_name in output:
        pytest.fail('SPI flash part name not recognized')

    m = re.search('page size (.+?) Bytes', output)
    if m:
        try:
            page_size = int(m.group(1))
        except ValueError:
            pytest.fail('SPI page size not recognized')

    m = re.search('erase size (.+?) KiB', output)
    if m:
        try:
            erase_size = int(m.group(1))
        except ValueError:
            pytest.fail('SPI erase size not recognized')

        erase_size *= 1024

    m = re.search('total (.+?) MiB', output)
    if m:
        try:
            total_size = int(m.group(1))
        except ValueError:
            pytest.fail('SPI total size not recognized')

        total_size *= 1024 * 1024

    m = re.search('Detected (.+?) with', output)
    if m:
        try:
            flash_part = m.group(1)
            assert flash_part == part_name
        except ValueError:
            pytest.fail('SPI flash part not recognized')

    global SPI_DATA
    SPI_DATA = {
        'page_size': page_size,
        'erase_size': erase_size,
        'total_size': total_size,
        'flash_part': flash_part,
        'timeout': timeout,
    }

def get_page_size():
    ''' Get the SPI page size from spi data '''
    return SPI_DATA['page_size']

def get_erase_size():
    ''' Get the SPI erase size from spi data '''
    return SPI_DATA['erase_size']

def get_total_size():
    ''' Get the SPI total size from spi data '''
    return SPI_DATA['total_size']

def get_flash_part():
    ''' Get the SPI flash part name from spi data '''
    return SPI_DATA['flash_part']

def get_timeout():
    ''' Get the SPI timeout from spi data '''
    return SPI_DATA['timeout']

def spi_erase_block(u_boot_console, erase_size, total_size):
    ''' Erase SPI flash memory block wise '''
    for start in range(0, total_size, erase_size):
        output = u_boot_console.run_command(f'sf erase {hex(start)} {hex(erase_size)}')
        assert EXPECTED_ERASE in output

@pytest.mark.buildconfigspec('cmd_sf')
def test_spi_erase_block(u_boot_console):
    ''' Test case to check SPI erase functionality by erasing memory regions
    block-wise '''

    min_f, max_f, loop = spi_find_freq_range(u_boot_console)
    i = 0
    while i < loop:
        spi_pre_commands(u_boot_console, random.randint(min_f, max_f))
        spi_erase_block(u_boot_console, get_erase_size(), get_total_size())
        i = i + 1

def spi_write_twice(u_boot_console, page_size, erase_size, total_size, timeout):
    ''' Random write till page size, random till size and full size '''
    addr = u_boot_utils.find_ram_base(u_boot_console)

    old_size = 0
    for size in (
        random.randint(4, page_size),
        random.randint(page_size, total_size),
        total_size,
    ):
        offset = random.randint(4, page_size)
        offset = offset & ~3
        size = size & ~3
        size = size - old_size
        output = u_boot_console.run_command(f'crc32 {hex(addr + total_size)} {hex(size)}')
        m = re.search('==> (.+?)$', output)
        if not m:
            pytest.fail('CRC32 failed')

        expected_crc32 = m.group(1)
        if old_size % page_size:
            old_size = int(old_size / page_size)
            old_size *= page_size

        if size % erase_size:
            erasesize = int(size / erase_size + 1)
            erasesize *= erase_size

        eraseoffset = int(old_size / erase_size)
        eraseoffset *= erase_size

        timeout = 100000000
        with u_boot_console.temporary_timeout(timeout):
            output = u_boot_console.run_command(
                f'sf erase {hex(eraseoffset)} {hex(erasesize)}'
            )
            assert EXPECTED_ERASE in output

        with u_boot_console.temporary_timeout(timeout):
            output = u_boot_console.run_command(
                f'sf write {hex(addr + total_size)} {hex(old_size)} {hex(size)}'
            )
            assert EXPECTED_WRITE in output
        with u_boot_console.temporary_timeout(timeout):
            output = u_boot_console.run_command(
                f'sf read {hex(addr + total_size + offset)} {hex(old_size)} {hex(size)}'
            )
            assert EXPECTED_READ in output
        output = u_boot_console.run_command(
            f'crc32 {hex(addr + total_size + offset)} {hex(size)}'
        )
        assert expected_crc32 in output
        old_size = size

@pytest.mark.buildconfigspec('cmd_bdi')
@pytest.mark.buildconfigspec('cmd_sf')
@pytest.mark.buildconfigspec('cmd_memory')
def test_spi_write_twice(u_boot_console):
    ''' Test to write data with random size twice for SPI '''
    min_f, max_f, loop = spi_find_freq_range(u_boot_console)
    i = 0
    while i < loop:
        spi_pre_commands(u_boot_console, random.randint(min_f, max_f))
        spi_write_twice(
            u_boot_console,
            get_page_size(),
            get_erase_size(),
            get_total_size(),
            get_timeout()
        )
        i = i + 1

def spi_write_continues(u_boot_console, page_size, erase_size, total_size, timeout):
    ''' Write with random size of data to continue SPI write case '''
    spi_erase_block(u_boot_console, erase_size, total_size)
    addr = u_boot_utils.find_ram_base(u_boot_console)

    output = u_boot_console.run_command(f'crc32 {hex(addr + 0x10000)} {hex(total_size)}')
    m = re.search('==> (.+?)$', output)
    if not m:
        pytest.fail('CRC32 failed')
    expected_crc32 = m.group(1)

    old_size = 0
    for size in (
        random.randint(4, page_size),
        random.randint(page_size, total_size),
        total_size,
    ):
        size = size & ~3
        size = size - old_size
        with u_boot_console.temporary_timeout(timeout):
            output = u_boot_console.run_command(
                f'sf write {hex(addr + 0x10000 + old_size)} {hex(old_size)} {hex(size)}'
            )
            assert EXPECTED_WRITE in output
        old_size += size

    with u_boot_console.temporary_timeout(timeout):
        output = u_boot_console.run_command(
            f'sf read {hex(addr + 0x10000 + total_size)} 0 {hex(total_size)}'
        )
        assert EXPECTED_READ in output

    output = u_boot_console.run_command(
        f'crc32 {hex(addr + 0x10000 + total_size)} {hex(total_size)}'
    )
    assert expected_crc32 in output

@pytest.mark.buildconfigspec('cmd_bdi')
@pytest.mark.buildconfigspec('cmd_sf')
@pytest.mark.buildconfigspec('cmd_memory')
def test_spi_write_continues(u_boot_console):
    ''' Test to write more random size data for SPI '''
    min_f, max_f, loop = spi_find_freq_range(u_boot_console)
    i = 0
    while i < loop:
        spi_pre_commands(u_boot_console, random.randint(min_f, max_f))
        spi_write_twice(
            u_boot_console,
            get_page_size(),
            get_erase_size(),
            get_total_size(),
            get_timeout(),
        )
        i = i + 1

def spi_read_twice(u_boot_console, page_size, total_size, timeout):
    ''' Read the whole SPI flash twice, random_size till full flash size,
    random till page size '''
    for size in random.randint(4, page_size), random.randint(4, total_size), total_size:
        addr = u_boot_utils.find_ram_base(u_boot_console)
        size = size & ~3
        with u_boot_console.temporary_timeout(timeout):
            output = u_boot_console.run_command(
                f'sf read {hex(addr + total_size)} 0 {hex(size)}'
            )
            assert EXPECTED_READ in output
        output = u_boot_console.run_command(f'crc32 {hex(addr + total_size)} {hex(size)}')
        m = re.search('==> (.+?)$', output)
        if not m:
            pytest.fail('CRC32 failed')
        expected_crc32 = m.group(1)
        with u_boot_console.temporary_timeout(timeout):
            output = u_boot_console.run_command(
                f'sf read {hex(addr + total_size + 10)} 0 {hex(size)}'
            )
            assert EXPECTED_READ in output
        output = u_boot_console.run_command(
            f'crc32 {hex(addr + total_size + 10)} {hex(size)}'
        )
        assert expected_crc32 in output

@pytest.mark.buildconfigspec('cmd_sf')
@pytest.mark.buildconfigspec('cmd_bdi')
@pytest.mark.buildconfigspec('cmd_memory')
def test_spi_read_twice(u_boot_console):
    ''' Test to read random data twice from SPI '''
    min_f, max_f, loop = spi_find_freq_range(u_boot_console)
    i = 0
    while i < loop:
        spi_pre_commands(u_boot_console, random.randint(min_f, max_f))
        spi_read_twice(u_boot_console, get_page_size(), get_total_size(), get_timeout())
        i = i + 1

def spi_erase_all(u_boot_console, total_size, timeout):
    ''' Erase the full chip SPI '''
    start = 0
    with u_boot_console.temporary_timeout(timeout):
        output = u_boot_console.run_command(f'sf erase {start} {hex(total_size)}')
        assert EXPECTED_ERASE in output

@pytest.mark.buildconfigspec('cmd_sf')
def test_spi_erase_all(u_boot_console):
    ''' Test to check full chip erase for SPI '''
    min_f, max_f, loop = spi_find_freq_range(u_boot_console)
    i = 0
    while i < loop:
        spi_pre_commands(u_boot_console, random.randint(min_f, max_f))
        spi_erase_all(u_boot_console, get_total_size(), get_timeout())
        i = i + 1

def flash_ops(
    u_boot_console, ops, start, size, offset=0, exp_ret=0, exp_str='', not_exp_str=''
):
    ''' Flash operations: erase, write and read '''

    f = u_boot_console.config.env.get('env__spi_device_test', None)
    if not f:
        timeout = 1000000

    timeout = f.get('timeout', 1000000)

    if ops == 'erase':
        with u_boot_console.temporary_timeout(timeout):
            output = u_boot_console.run_command(f'sf erase {hex(start)} {hex(size)}')
    else:
        with u_boot_console.temporary_timeout(timeout):
            output = u_boot_console.run_command(
                f'sf {ops} {hex(offset)} {hex(start)} {hex(size)}'
            )

    if exp_str:
        assert exp_str in output
    if not_exp_str:
        assert not_exp_str not in output

    ret_code = u_boot_console.run_command('echo $?')
    if exp_ret >= 0:
        assert ret_code.endswith(str(exp_ret))

    return output, ret_code

def spi_unlock_exit(u_boot_console, addr, size):
    ''' Unlock the flash before making it fail '''
    u_boot_console.run_command(f'sf protect unlock {hex(addr)} {hex(size)}')
    assert False, 'FAIL: Flash lock is unable to protect the data!'

def find_prot_region(lock_addr, lock_size):
    ''' Get the protected and un-protected region of flash '''
    total_size = get_total_size()
    erase_size = get_erase_size()

    if lock_addr < (total_size // 2):
        sect_num = (lock_addr + lock_size) // erase_size
        x = 1
        while x < sect_num:
            x *= 2
        prot_start = 0
        prot_size = x * erase_size
        unprot_start = prot_start + prot_size
        unprot_size = total_size - unprot_start
    else:
        sect_num = (total_size - lock_addr) // erase_size
        x = 1
        while x < sect_num:
            x *= 2
        prot_start = total_size - (x * erase_size)
        prot_size = total_size - prot_start
        unprot_start = 0
        unprot_size = prot_start

    return prot_start, prot_size, unprot_start, unprot_size

def protect_ops(u_boot_console, lock_addr, lock_size, ops="unlock"):
    ''' Run the command to lock or Unlock the flash '''
    u_boot_console.run_command(f'sf protect {ops} {hex(lock_addr)} {hex(lock_size)}')
    output = u_boot_console.run_command('echo $?')
    if ops == "lock" and not output.endswith('0'):
        u_boot_console.run_command(f'sf protect unlock {hex(lock_addr)} {hex(lock_size)}')
        assert False, "sf protect lock command exits with non-zero return code"
    assert output.endswith('0')

def erase_write_ops(u_boot_console, start, size):
    ''' Basic erase and write operation for flash '''
    addr = u_boot_utils.find_ram_base(u_boot_console)
    flash_ops(u_boot_console, 'erase', start, size, 0, 0, EXPECTED_ERASE)
    flash_ops(u_boot_console, 'write', start, size, addr, 0, EXPECTED_WRITE)

def spi_lock_unlock(u_boot_console, lock_addr, lock_size):
    ''' Lock unlock operations for SPI family flash '''
    addr = u_boot_utils.find_ram_base(u_boot_console)
    erase_size = get_erase_size()

    # Find the protected/un-protected region
    prot_start, prot_size, unprot_start, unprot_size = find_prot_region(lock_addr, lock_size)

    # Check erase/write operation before locking
    erase_write_ops(u_boot_console, prot_start, prot_size)

    # Locking the flash
    protect_ops(u_boot_console, lock_addr, lock_size, 'lock')

    # Check erase/write operation after locking
    output, ret_code = flash_ops(u_boot_console, 'erase', prot_start, prot_size, 0, -1)
    if not any(error in output for error in EXPECTED_ERASE_ERRORS) or ret_code.endswith(
        '0'
    ):
        spi_unlock_exit(u_boot_console, lock_addr, lock_size)

    output, ret_code = flash_ops(
        u_boot_console, 'write', prot_start, prot_size, addr, -1
    )
    if not any(error in output for error in EXPECTED_WRITE_ERRORS) or ret_code.endswith(
        '0'
    ):
        spi_unlock_exit(u_boot_console, lock_addr, lock_size)

    # Check locked sectors
    sect_lock_start = random.randrange(prot_start, (prot_start + prot_size), erase_size)
    if prot_size > erase_size:
        sect_lock_size = random.randrange(
            erase_size, (prot_start + prot_size - sect_lock_start), erase_size
        )
    else:
        sect_lock_size = erase_size
    sect_write_size = random.randint(1, sect_lock_size)

    output, ret_code = flash_ops(
        u_boot_console, 'erase', sect_lock_start, sect_lock_size, 0, -1
    )
    if not any(error in output for error in EXPECTED_ERASE_ERRORS) or ret_code.endswith(
        '0'
    ):
        spi_unlock_exit(u_boot_console, lock_addr, lock_size)

    output, ret_code = flash_ops(
        u_boot_console, 'write', sect_lock_start, sect_write_size, addr, -1
    )
    if not any(error in output for error in EXPECTED_WRITE_ERRORS) or ret_code.endswith(
        '0'
    ):
        spi_unlock_exit(u_boot_console, lock_addr, lock_size)

    # Check unlocked sectors
    if unprot_size != 0:
        sect_unlock_start = random.randrange(
            unprot_start, (unprot_start + unprot_size), erase_size
        )
        if unprot_size > erase_size:
            sect_unlock_size = random.randrange(
                erase_size, (unprot_start + unprot_size - sect_unlock_start), erase_size
            )
        else:
            sect_unlock_size = erase_size
        sect_write_size = random.randint(1, sect_unlock_size)

        output, ret_code = flash_ops(
            u_boot_console, 'erase', sect_unlock_start, sect_unlock_size, 0, -1
        )
        if EXPECTED_ERASE not in output or ret_code.endswith('1'):
            spi_unlock_exit(u_boot_console, lock_addr, lock_size)

        output, ret_code = flash_ops(
            u_boot_console, 'write', sect_unlock_start, sect_write_size, addr, -1
        )
        if EXPECTED_WRITE not in output or ret_code.endswith('1'):
            spi_unlock_exit(u_boot_console, lock_addr, lock_size)

    # Unlocking the flash
    protect_ops(u_boot_console, lock_addr, lock_size, 'unlock')

    # Check erase/write operation after un-locking
    erase_write_ops(u_boot_console, prot_start, prot_size)

    # Check previous locked sectors
    sect_lock_start = random.randrange(prot_start, (prot_start + prot_size), erase_size)
    if prot_size > erase_size:
        sect_lock_size = random.randrange(
            erase_size, (prot_start + prot_size - sect_lock_start), erase_size
        )
    else:
        sect_lock_size = erase_size
    sect_write_size = random.randint(1, sect_lock_size)

    flash_ops(
        u_boot_console, 'erase', sect_lock_start, sect_lock_size, 0, 0, EXPECTED_ERASE
    )
    flash_ops(
        u_boot_console,
        'write',
        sect_lock_start,
        sect_write_size,
        addr,
        0,
        EXPECTED_WRITE,
    )

@pytest.mark.buildconfigspec('cmd_bdi')
@pytest.mark.buildconfigspec('cmd_sf')
@pytest.mark.buildconfigspec('cmd_memory')
def test_spi_lock_unlock(u_boot_console):
    ''' Test to check the lock-unlock functionality for SPI family flash '''
    min_f, max_f, loop = spi_find_freq_range(u_boot_console)
    flashes = u_boot_console.config.env.get('env__spi_lock_unlock', False)
    if not flashes:
        pytest.skip('No supported flash list for lock/unlock provided')

    i = 0
    while i < loop:
        spi_pre_commands(u_boot_console, random.randint(min_f, max_f))
        total_size = get_total_size()
        flash_part = get_flash_part()

        flashes_list = flashes.get('supported_flash', None).split(',')
        flashes_list = [x.strip() for x in flashes_list]
        if flash_part not in flashes_list:
            pytest.skip('Detected flash does not support lock/unlock')

        # For lower half of memory
        lock_addr = random.randint(0, (total_size // 2) - 1)
        lock_size = random.randint(1, ((total_size // 2) - lock_addr))
        spi_lock_unlock(u_boot_console, lock_addr, lock_size)

        # For upper half of memory
        lock_addr = random.randint((total_size // 2), total_size - 1)
        lock_size = random.randint(1, (total_size - lock_addr))
        spi_lock_unlock(u_boot_console, lock_addr, lock_size)

        # For entire flash
        lock_addr = random.randint(0, total_size - 1)
        lock_size = random.randint(1, (total_size - lock_addr))
        spi_lock_unlock(u_boot_console, lock_addr, lock_size)

        i = i + 1

@pytest.mark.buildconfigspec('cmd_bdi')
@pytest.mark.buildconfigspec('cmd_sf')
@pytest.mark.buildconfigspec('cmd_memory')
def test_spi_negative(u_boot_console):
    ''' Negative tests for SPI '''
    min_f, max_f, loop = spi_find_freq_range(u_boot_console)
    spi_pre_commands(u_boot_console, random.randint(min_f, max_f))
    total_size = get_total_size()
    erase_size = get_erase_size()
    page_size = get_page_size()
    addr = u_boot_utils.find_ram_base(u_boot_console)
    i = 0
    while i < loop:
        # Erase negative test
        start = random.randint(0, total_size)
        esize = erase_size

        # If erasesize is not multiple of flash's erase size
        while esize % erase_size == 0:
            esize = random.randint(0, total_size - start)

        error_msg = 'Erased: ERROR'
        flash_ops(
            u_boot_console, 'erase', start, esize, 0, 1, error_msg, EXPECTED_ERASE
        )

        # If eraseoffset exceeds beyond flash size
        eoffset = random.randint(total_size, (total_size + int(0x1000000)))
        error_msg = 'Offset exceeds device limit'
        flash_ops(
            u_boot_console, 'erase', eoffset, esize, 0, 1, error_msg, EXPECTED_ERASE
        )

        # If erasesize exceeds beyond flash size
        esize = random.randint((total_size - start), (total_size + int(0x1000000)))
        error_msg = 'ERROR: attempting erase past flash size'
        flash_ops(
            u_boot_console, 'erase', start, esize, 0, 1, error_msg, EXPECTED_ERASE
        )

        # If erase size is 0
        esize = 0
        error_msg = None
        flash_ops(
            u_boot_console, 'erase', start, esize, 0, 1, error_msg, EXPECTED_ERASE
        )

        # If erasesize is less than flash's page size
        esize = random.randint(0, page_size)
        start = random.randint(0, (total_size - page_size))
        error_msg = 'Erased: ERROR'
        flash_ops(
            u_boot_console, 'erase', start, esize, 0, 1, error_msg, EXPECTED_ERASE
        )

        # Write/Read negative test
        # if Write/Read size exceeds beyond flash size
        offset = random.randint(0, total_size)
        size = random.randint((total_size - offset), (total_size + int(0x1000000)))
        error_msg = 'Size exceeds partition or device limit'
        flash_ops(
            u_boot_console, 'write', offset, size, addr, 1, error_msg, EXPECTED_WRITE
        )
        flash_ops(
            u_boot_console, 'read', offset, size, addr, 1, error_msg, EXPECTED_READ
        )

        # if Write/Read offset exceeds beyond flash size
        offset = random.randint(total_size, (total_size + int(0x1000000)))
        size = random.randint(0, total_size)
        error_msg = 'Offset exceeds device limit'
        flash_ops(
            u_boot_console, 'write', offset, size, addr, 1, error_msg, EXPECTED_WRITE
        )
        flash_ops(
            u_boot_console, 'read', offset, size, addr, 1, error_msg, EXPECTED_READ
        )

        # if Write/Read size is 0
        offset = random.randint(0, 2)
        size = 0
        error_msg = None
        flash_ops(
            u_boot_console, 'write', offset, size, addr, 1, error_msg, EXPECTED_WRITE
        )
        flash_ops(
            u_boot_console, 'read', offset, size, addr, 1, error_msg, EXPECTED_READ
        )

        i = i + 1
