'''Source to provide the firmware OTA service for IoT devices'''
import os
import sys


class FirmwareService():
    '''Class to provide the firmware service'''

    _firmware_data = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'firmware_data'))
    _projects = {}


    def __init__(self):
        '''Read the settings and create service'''


    def addProject(self, project, path):
        '''Add path for firmware from external

        Args:
            project (str): Project name
            path (str): Path to firmware files
        '''
        self._projects[project] = path


    def getFirmwareFileName(self, project, deveui, hw_major, hw_minor, fw_major, fw_minor, fw_patch):
        '''Return the firmware name we have by given argumentsdatetime A combination of a date and a time.

        Args:
            project (str): Name of project
            deveui (array(int)): Hardware DEVEUI = ID
            hw_major (int): Hardware major version
            hw_minor (int): Hardware minor version
            fw_major (int): Firmware major version
            fw_minor (int): Firmware minor version
            fw_patch (int): Firmware patch number

        Returns:
            [str]: Filename of firmware
        '''
        if project in self._projects:
            path = self._projects[project]
        elif project:
            path = os.path.join(self._firmware_data, project)
        else:
            path = self._firmware_data

        fn_str = 'firmware_hw{:d}.{:02d}_fw{:d}.{:02d}.{:d}.bin'
        fn = fn_str.format(hw_major, hw_minor, fw_major, fw_minor, fw_patch)
        return os.path.join(path, fn)


    def getNextFirmwareFileName(self, project, deveui, hw_major, hw_minor, fw_major, fw_minor, fw_patch):
        '''Get filename of the next available version

        Args:
            project (str): Name of project
            deveui (array(int)): Hardware DEVEUI = ID
            hw_major (int): Hardware major version
            hw_minor (int): Hardware minor version
            fw_major (int): Firmware major version
            fw_minor (int): Firmware minor version
            fw_patch (int): Firmware patch number

        Returns:
            [int, int, int, str, str)]: Return major, minor and patch number, path to next firmware and status message
        '''
        file_path = self.getFirmwareFileName(project, deveui, hw_major, hw_minor, fw_major, fw_minor, fw_patch)
        if not os.path.isfile(file_path):
            return (-1,-1,-1, file_path, 'unknown firmware')
        file_path = self.getFirmwareFileName(project, deveui, hw_major, hw_minor, fw_major, fw_minor, fw_patch + 1)
        if os.path.isfile(file_path):
            return (fw_major, fw_minor, fw_patch + 1, file_path, 'new patch available')
        file_path = self.getFirmwareFileName(project, deveui, hw_major, hw_minor, fw_major, fw_minor + 1, 0)
        if os.path.isfile(file_path):
            return (fw_major, fw_minor + 1, 0, file_path, 'new minor version available')
        file_path = self.getFirmwareFileName(project, deveui, hw_major, hw_minor, fw_major + 1, 0, 0)
        if os.path.isfile(file_path):
            return (fw_major + 1, 0, 0, file_path, 'new major version available')
        return (fw_major, fw_minor, fw_patch, file_path, 'no newer version available')
