#!/usr/bin/env python3
# Copyright (c) 2020-2021 Project CHIP Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Flash an NRF5 device.

This is layered so that a caller can perform individual operations
through an `Flasher` instance, or operations according to a command line.
For `Flasher`, see the class documentation. For the parse_command()
interface or standalone execution:

usage: nrfconnect_firmware_utils.py [-h] [--verbose] [--erase]
                                    [--application FILE]
                                    [--verify_application] [--reset]
                                    [--skip_reset] [--nrfjprog FILE]
                                    [--snr SERIAL] [--family FAMILY]

Flash NRF5 device

optional arguments:
  -h, --help            show this help message and exit

configuration:
  --verbose, -v         Report more verbosely
  --nrfjprog FILE       File name of the nrfjprog executable
  --snr SERIAL, --serial SERIAL, -s SERIAL
                        Serial number of device to flash
  --family FAMILY       NRF5 device family

operations:
  --erase               Erase device
  --application FILE    Flash an image
  --verify_application, --verify-application
                        Verify the image after flashing
  --reset               Reset device after flashing
  --skip_reset, --skip-reset
                        Do not reset device after flashing
"""

import os
import sys

import firmware_utils

# Additional options that can be use to configure an `Flasher`
# object (as dictionary keys) and/or passed as command line options.
NRF5_OPTIONS = {
    # Configuration options define properties used in flashing operations.
    'configuration': {
        # Tool configuration options.
        'nrfjprog': {
            'help': 'File name of the nrfjprog executable',
            'default': 'nrfjprog',
            'argparse': {
                'metavar': 'FILE'
            },
            'command': [
                '{nrfjprog}',
                {'optional': 'family'},
                {'optional': 'snr'},
                ()
            ],
            'verify': ['{nrfjprog}', '--version'],
            'error':
                """\
                Unable to execute {nrfjprog}.

                Please ensure that this tool is installed and
                available. See the NRF5 example README for
                installation instructions.

                """,
        },
        'snr': {
            'help': 'Serial number of device to flash',
            'default': None,
            'alias': ['--serial', '-s'],
            'argparse': {
                'metavar': 'SERIAL'
            },
        },

        # Device configuration options.
        'family': {
            'help': 'NRF5 device family',
            'default': None,
            'argparse': {
                'metavar': 'FAMILY'
            },
        },
    },
}


class Flasher(firmware_utils.Flasher):
    """Manage nrf5 flashing."""

    def __init__(self, **options):
        super().__init__(platform='NRF5', module=__name__, **options)
        self.define_options(NRF5_OPTIONS)

    def erase(self):
        """Perform nrfjprog --eraseall"""
        return self.run_tool('nrfjprog', ['--eraseall'], name='Erase all')

    def verify(self, image):
        """Verify image."""
        return self.run_tool('nrfjprog',
                             ['--quiet', '--verify', image],
                             name='Verify',
                             pass_message='Verified',
                             fail_message='Not verified',
                             fail_level=2)

    def flash(self, image):
        """Flash image."""
        return self.run_tool('nrfjprog',
                             ['--program', image, '--sectoranduicrerase'],
                             name='Flash')

    def reset(self):
        """Reset the device."""
        return self.run_tool('nrfjprog', ['--reset'], name='Reset')

    def actions(self):
        """Perform actions on the device according to self.option."""
        self.log(3, 'Options:', self.option)

        if self.option.erase:
            if self.erase().err:
                return self

        if self.option.application:
            application = self.option.application
            if self.flash(application).err:
                return self
            if self.option.verify_application:
                if self.verify(application).err:
                    return self
            if self.option.reset is None:
                self.option.reset = True

        if self.option.reset:
            if self.reset().err:
                return self

        return self

# Mobly integration


class Nrf5Platform:
    def __init__(self, flasher_args):
        self.flasher = Flasher(**flasher_args)

    def flash(self):
        self.flasher.flash_command([os.getcwd()])


def verify_platform_args(platform_args):
    required_args = ['application']
    for r in required_args:
        if not r in platform_args:
            raise ValueError("Required argument %s missing" % r)


def create_platform(platform_args):
    verify_platform_args(platform_args[0])
    return Nrf5Platform(platform_args[0])

# End of Mobly integration


if __name__ == '__main__':
    sys.exit(Flasher().flash_command(sys.argv))
