#!/usr/bin/env python3
#
# Copyright (c) 2020 Nuvoton Technology Corporation
#
# SPDX-License-Identifier: Apache-2.0

# This file contains general functions for ECST application

import sys
import argparse
from colorama import Fore

INVALID_INPUT = -1
EXIT_FAILURE_STATUS = 1

# Header common fields
FW_HDR_CRC_DISABLE = 0x00
FW_HDR_CRC_ENABLE = 0x02
FW_CRC_DISABLE = 0x00
FW_CRC_ENABLE = 0x02

SPI_CLOCK_RATIO_1 = 0x00
SPI_CLOCK_RATIO_2 = 0x08

SPI_UNLIMITED_BURST_DISABLE = 0x00
SPI_UNLIMITED_BURST_ENABLE = 0x08

# Verbose related values
NO_VERBOSE = 0
REG_VERBOSE = 1
SUPER_VERBOSE = 1

# argument default values.
DEFAULT_MODE = "bt"
SPI_MAX_CLOCK_DEFAULT = "20"
FLASH_SIZE_DEFAULT = "16"
SPI_CLOCK_RATIO_DEFAULT = 1
PASTE_FIRMWARE_HEADER_DEFAULT = 0x00000000
DEFAULT_VERBOSE = NO_VERBOSE
SPI_MODE_VAL_DEFAULT = 'normal'
SPI_UNLIMITED_BURST_DEFAULT = SPI_UNLIMITED_BURST_DISABLE
FW_HDR_CRC_DEFAULT = FW_HDR_CRC_ENABLE
FW_CRC_DEFAULT = FW_CRC_ENABLE
FW_CRC_START_OFFSET_DEFAULT = 0x0
POINTER_OFFSET_DEFAULT = 0x0

# Chips: convert from name to index.
CHIPS_INFO = {'npcx7m5': {'ram_address': 0x100A8000, 'ram_size': 0x20000},
              'npcx7m6': {'ram_address': 0x10090000, 'ram_size': 0x40000},
              'npcx7m7': {'ram_address': 0x10070000, 'ram_size': 0x60000}}
DEFAULT_CHIP = 'npcx7m6'

# RAM related values
RAM_ADDR = 0x00
RAM_SIZE = 0x01

class EcstArgs:
    """creates an arguments object for the ECST,
    the arguments are taken from the command line and/or
    argument file
    """
    error_args = None

    mode = DEFAULT_MODE
    help = False
    verbose = DEFAULT_VERBOSE
    super_verbose = False
    input = None
    output = None
    args_file = None
    chip_name = DEFAULT_CHIP
    chip_ram_address = CHIPS_INFO[DEFAULT_CHIP]['ram_address']
    chip_ram_size = CHIPS_INFO[DEFAULT_CHIP]['ram_address']
    firmware_header_crc = FW_HDR_CRC_DEFAULT
    firmware_crc = FW_CRC_DEFAULT
    spi_flash_maximum_clock = SPI_MAX_CLOCK_DEFAULT
    spi_flash_clock_ratio = SPI_CLOCK_RATIO_DEFAULT
    unlimited_burst_mode = SPI_UNLIMITED_BURST_DEFAULT
    spi_flash_read_mode = SPI_MODE_VAL_DEFAULT
    firmware_load_address = None
    firmware_entry_point = None
    use_arm_reset = True
    firmware_crc_start = FW_CRC_START_OFFSET_DEFAULT
    firmware_crc_size = None
    firmware_length = None
    flash_size = FLASH_SIZE_DEFAULT
    paste_firmware_header = PASTE_FIRMWARE_HEADER_DEFAULT
    pointer = POINTER_OFFSET_DEFAULT
    bh_offset = None

    def __init__(self):

        arguments = _create_parser("")
        valid_arguments = arguments[0]
        invalid_arguments = arguments[1]
        self.error_args = invalid_arguments

        _populate_args(self, valid_arguments)
        _populate_chip_fields(self)

def _populate_chip_fields(self):
    """populate the chip related fields for the ecst"""
    self.chip_name = self.chip_name
    chip = str(self.chip_name).lower()

    if chip not in CHIPS_INFO:
        self.chip_name = INVALID_INPUT
        return

    self.chip_ram_address = CHIPS_INFO[chip]['ram_address']
    self.chip_ram_size = CHIPS_INFO[chip]['ram_size']
    if self.firmware_load_address is None:
        self.firmware_load_address = self.chip_ram_address

def _populate_args(self, argument_list):
    """populate the ecst arguments according to the command line/ args file"""
    for arg in vars(argument_list):
        if (arg == "input") & (argument_list.input is not None):
            self.input = argument_list.input

        elif (arg == "output") & (argument_list.output is not None):
            self.output = argument_list.output

        elif (arg == "chip") & (argument_list.chip is not None):
            self.chip_name = argument_list.chip
            _populate_chip_fields(self)

        elif (arg == "verbose") & argument_list.verbose:
            self.verbose = REG_VERBOSE

        elif (arg == "super_verbose") & argument_list.super_verbose:
            self.verbose = SUPER_VERBOSE

        elif (arg == "spi_flash_maximum_clock") & \
                (argument_list.spi_flash_maximum_clock is not None):
            self.spi_flash_maximum_clock =\
                argument_list.spi_flash_maximum_clock

        elif (arg == "spi_flash_clock_ratio") & \
                (argument_list.spi_flash_clock_ratio is not None):
            if argument_list.spi_flash_clock_ratio.isdigit():
                self.spi_flash_clock_ratio =\
                    int(argument_list.spi_flash_clock_ratio)
            else:
                self.spi_flash_clock_ratio = INVALID_INPUT

        elif (arg == "firmware_header_crc") &\
                argument_list.firmware_header_crc:
            self.firmware_header_crc = FW_HDR_CRC_DISABLE

        elif (arg == "firmware_crc") & argument_list.firmware_crc:
            self.firmware_crc = FW_CRC_DISABLE

        elif (arg == "spi_read_mode") &\
                (argument_list.spi_read_mode is not None):

            self.spi_flash_read_mode = argument_list.spi_read_mode

        elif (arg == "flash_size") & (argument_list.flash_size is not None):
            self.flash_size = argument_list.flash_size

        elif (arg == "paste_firmware_header") & \
                (argument_list.paste_firmware_header is not None):
            if _is_hex(argument_list.paste_firmware_header):
                self.paste_firmware_header =\
                    int(argument_list.paste_firmware_header, 16)
            else:
                self.paste_firmware_header = INVALID_INPUT

def _create_parser(arg_list):
    """create argument parser according to pre-defined arguments

    :param arg_list: when empty, parses command line arguments,
    else parses the given string
    """

    parser = argparse.ArgumentParser(conflict_handler='resolve')
    parser.add_argument("-i", nargs='?', dest="input")
    parser.add_argument("-o", nargs='?', dest="output")
    parser.add_argument("-chip", dest="chip")
    parser.add_argument("-v", action="store_true", dest="verbose")
    parser.add_argument("-vv", action="store_true", dest="super_verbose")
    parser.add_argument("-nohcrc", action="store_true",
                        dest="firmware_header_crc")
    parser.add_argument("-nofcrc", action="store_true", dest="firmware_crc")
    parser.add_argument("-spimaxclk", nargs='?',
                        dest="spi_flash_maximum_clock")
    parser.add_argument("-spiclkratio", nargs='?',
                        dest="spi_flash_clock_ratio")
    parser.add_argument("-spireadmode", nargs='?', dest="spi_read_mode")
    parser.add_argument("-flashsize", nargs='?', dest="flash_size")
    parser.add_argument("-ph", nargs='?', dest="paste_firmware_header")

    args = parser.parse_known_args(arg_list.split())

    if arg_list == "":
        args = parser.parse_known_args()

    return args

def _file_to_line(arg_file):
    """helper to convert a text file to one line string
    used to parse the arguments in a given argfile

    :param arg_file: the file to manipulate
    """
    with open(arg_file, "r") as arg_file_to_read:
        data = arg_file_to_read.read().strip()
    arg_file_to_read.close()

    return data

def _is_hex(val):
    """helper to determine whether an input is a hex
    formatted number

    :param val: input to be checked
    """
    if val.startswith("0x") or val.startswith("0X"):
        val = val[2:]
    hex_digits = set("0123456789abcdefABCDEF")
    for char in val:
        if char not in hex_digits:
            return False
    return True

def exit_with_failure(message):
    """formatted failure message printer, prints the
    relevant error message and exits the application.

    :param message: the error message to be printed
    """

    message = '\n' + message
    message += '\n'
    message += '******************************\n'
    message += '***        FAILED          ***\n'
    message += '******************************\n'
    print(Fore.RED + message)

    sys.exit(EXIT_FAILURE_STATUS)
