"""
Copyright 2020 The Magma Authors.

This source code is licensed under the BSD-style license found in the
LICENSE file in the root directory of this source tree.

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.
"""

import time
from abc import ABC, abstractmethod
from collections import namedtuple
from typing import Any, Optional

import metrics

from configuration.service_configs import load_service_config
from data_models.data_model import InvalidTrParamPath
from data_models.data_model_parameters import ParameterName
from device_config.configuration_init import build_desired_config
from exceptions import ConfigurationError, Tr069Error
from logger import EnodebdLogger as logger
from state_machines.acs_state_utils import (
    does_inform_have_event,
    get_all_objects_to_add,
    get_all_objects_to_delete,
    get_all_param_values_to_set,
    get_obj_param_values_to_set,
    get_object_params_to_get,
    get_optional_param_to_check,
    get_param_values_to_set,
    get_params_to_get,
    parse_get_parameter_values_response,
    process_inform_message,
)
from state_machines.enb_acs import EnodebAcsStateMachine
from state_machines.timer import StateMachineTimer
from tr069 import models

AcsMsgAndTransition = namedtuple(
    'AcsMsgAndTransition', ['msg', 'next_state'],
)

AcsReadMsgResult = namedtuple(
    'AcsReadMsgResult', ['msg_handled', 'next_state'],
)


class EnodebAcsState(ABC):
    """
    State class for the Enodeb state machine

    States can transition after reading a message from the eNB, sending a
    message out to the eNB, or when a timer completes. As such, some states
    are only responsible for message sending, and others are only responsible
    for reading incoming messages.

    In the constructor, set up state transitions.
    """

    def __init__(self):
        self._acs = None

    def enter(self) -> None:
        """
        Set up your timers here. Call transition(..) on the ACS when the timer
        completes or throw an error
        """
        pass

    def exit(self) -> None:
        """Destroy timers here"""
        pass

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        """
        Args: message: tr069 message
        Returns: name of the next state, if transition required
        """
        raise ConfigurationError(
            '%s should implement read_msg() if it '
            'needs to handle message reading' % self.__class__.__name__,
        )

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        """
        Produce a message to send back to the eNB.

        Args:
            message: TR-069 message which was already processed by read_msg

        Returns: Message and possible transition
        """
        raise ConfigurationError(
            '%s should implement get_msg() if it '
            'needs to produce messages' % self.__class__.__name__,
        )

    @property
    def acs(self) -> EnodebAcsStateMachine:
        return self._acs

    @acs.setter
    def acs(self, val: EnodebAcsStateMachine) -> None:
        self._acs = val

    @abstractmethod
    def state_description(self) -> str:
        """ Provide a few words about what the state represents """
        pass


class WaitInformState(EnodebAcsState):
    """
    This state indicates that no Inform message has been received yet, or
    that no Inform message has been received for a long time.

    This state is used to handle an Inform message that arrived when enodebd
    already believes that the eNB is connected. As such, it is unclear to
    enodebd whether the eNB is just sending another Inform, or if a different
    eNB was plugged into the same interface.
    """

    def __init__(
        self,
        acs: EnodebAcsStateMachine,
        when_done: str,
        when_boot: Optional[str] = None,
    ):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done
        self.boot_transition = when_boot
        self.has_enb_just_booted = False

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        """
        Args:
            message: models.Inform Tr069 Inform message
        """
        if not isinstance(message, models.Inform):
            return AcsReadMsgResult(False, None)
        process_inform_message(
            message, self.acs.data_model,
            self.acs.device_cfg,
        )
        if does_inform_have_event(message, '1 BOOT'):
            return AcsReadMsgResult(True, self.boot_transition)
        return AcsReadMsgResult(True, None)

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        """ Reply with InformResponse """
        response = models.InformResponse()
        # Set maxEnvelopes to 1, as per TR-069 spec
        response.MaxEnvelopes = 1
        return AcsMsgAndTransition(response, self.done_transition)

    def state_description(self) -> str:
        return 'Waiting for an Inform'


class GetRPCMethodsState(EnodebAcsState):
    """
    After the first Inform message from boot, it is expected that the eNB
    will try to learn the RPC methods of the ACS.
    """

    def __init__(self, acs: EnodebAcsStateMachine, when_done: str, when_skip: str):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done
        self.skip_transition = when_skip

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        # If this is a regular Inform, not after a reboot we'll get an empty
        if isinstance(message, models.DummyInput):
            return AcsReadMsgResult(True, self.skip_transition)
        if not isinstance(message, models.GetRPCMethods):
            return AcsReadMsgResult(False, self.done_transition)
        return AcsReadMsgResult(True, None)

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        resp = models.GetRPCMethodsResponse()
        resp.MethodList = models.MethodList()
        RPC_METHODS = ['Inform', 'GetRPCMethods', 'TransferComplete']
        resp.MethodList.arrayType = 'xsd:string[%d]' \
                                          % len(RPC_METHODS)
        resp.MethodList.string = RPC_METHODS
        return AcsMsgAndTransition(resp, self.done_transition)

    def state_description(self) -> str:
        return 'Waiting for incoming GetRPC Methods after boot'


class BaicellsRemWaitState(EnodebAcsState):
    """
    We've already received an Inform message. This state is to handle a
    Baicells eNodeB issue.

    After eNodeB is rebooted, hold off configuring it for some time to give
    time for REM to run. This is a BaiCells eNodeB issue that doesn't support
    enabling the eNodeB during initial REM.

    In this state, just hang at responding to Inform, and then ending the
    TR-069 session.
    """

    CONFIG_DELAY_AFTER_BOOT = 600

    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done
        self.rem_timer = None

    def enter(self):
        self.rem_timer = StateMachineTimer(self.CONFIG_DELAY_AFTER_BOOT)
        logger.info(
            'Holding off of eNB configuration for %s seconds. '
            'Will resume after eNB REM process has finished. ',
            self.CONFIG_DELAY_AFTER_BOOT,
        )

    def exit(self):
        self.rem_timer = None

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        if not isinstance(message, models.Inform):
            return AcsReadMsgResult(False, None)
        process_inform_message(
            message, self.acs.data_model,
            self.acs.device_cfg,
        )
        return AcsReadMsgResult(True, None)

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        if self.rem_timer.is_done():
            return AcsMsgAndTransition(
                models.DummyInput(),
                self.done_transition,
            )
        return AcsMsgAndTransition(models.DummyInput(), None)

    def state_description(self) -> str:
        remaining = self.rem_timer.seconds_remaining()
        return 'Waiting for eNB REM to run for %d more seconds before ' \
               'resuming with configuration.' % remaining


class WaitEmptyMessageState(EnodebAcsState):
    def __init__(
        self,
        acs: EnodebAcsStateMachine,
        when_done: str,
        when_missing: Optional[str] = None,
    ):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done
        self.unknown_param_transition = when_missing

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        """
        It's expected that we transition into this state right after receiving
        an Inform message and replying with an InformResponse. At that point,
        the eNB sends an empty HTTP request (aka DummyInput) to initiate the
        rest of the provisioning process
        """
        if not isinstance(message, models.DummyInput):
            logger.debug("Ignoring message %s", str(type(message)))
            return AcsReadMsgResult(msg_handled=False, next_state=None)
        if self.unknown_param_transition:
            if get_optional_param_to_check(self.acs.data_model):
                return AcsReadMsgResult(
                    msg_handled=True,
                    next_state=self.unknown_param_transition,
                )
        return AcsReadMsgResult(
            msg_handled=True,
            next_state=self.done_transition,
        )

    def get_msg(self, message: Any) -> AcsReadMsgResult:
        """
        Return a dummy message waiting for the empty message from CPE
        """
        request = models.DummyInput()
        return AcsMsgAndTransition(msg=request, next_state=None)

    def state_description(self) -> str:
        return 'Waiting for empty message from eNodeB'


class CheckOptionalParamsState(EnodebAcsState):
    def __init__(
            self,
            acs: EnodebAcsStateMachine,
            when_done: str,
    ):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done
        self.optional_param = None

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        self.optional_param = get_optional_param_to_check(self.acs.data_model)
        if self.optional_param is None:
            raise Tr069Error('Invalid State')
        # Generate the request
        request = models.GetParameterValues()
        request.ParameterNames = models.ParameterNames()
        request.ParameterNames.arrayType = 'xsd:string[1]'
        request.ParameterNames.string = []
        path = self.acs.data_model.get_parameter(self.optional_param).path
        request.ParameterNames.string.append(path)
        return AcsMsgAndTransition(request, None)

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        """ Process either GetParameterValuesResponse or a Fault """
        if type(message) == models.Fault:
            self.acs.data_model.set_parameter_presence(
                self.optional_param,
                False,
            )
        elif type(message) == models.GetParameterValuesResponse:
            name_to_val = parse_get_parameter_values_response(
                self.acs.data_model,
                message,
            )
            logger.debug(
                'Received CPE parameter values: %s',
                str(name_to_val),
            )
            for name, val in name_to_val.items():
                self.acs.data_model.set_parameter_presence(
                    self.optional_param,
                    True,
                )
                magma_val = self.acs.data_model.transform_for_magma(name, val)
                self.acs.device_cfg.set_parameter(name, magma_val)
        else:
            return AcsReadMsgResult(False, None)

        if get_optional_param_to_check(self.acs.data_model) is not None:
            return AcsReadMsgResult(True, None)
        return AcsReadMsgResult(True, self.done_transition)

    def state_description(self) -> str:
        return 'Checking if some optional parameters exist in data model'


class SendGetTransientParametersState(EnodebAcsState):
    """
    Periodically read eNodeB status. Note: keep frequency low to avoid
    backing up large numbers of read operations if enodebd is busy.
    Some eNB parameters are read only and updated by the eNB itself.
    """
    PARAMETERS = [
        ParameterName.OP_STATE,
        ParameterName.RF_TX_STATUS,
        ParameterName.GPS_STATUS,
        ParameterName.PTP_STATUS,
        ParameterName.MME_STATUS,
        ParameterName.GPS_LAT,
        ParameterName.GPS_LONG,
    ]

    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        if not isinstance(message, models.DummyInput):
            return AcsReadMsgResult(False, None)
        return AcsReadMsgResult(True, None)

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        request = models.GetParameterValues()
        request.ParameterNames = models.ParameterNames()
        request.ParameterNames.string = []
        for name in self.PARAMETERS:
            # Not all data models have these parameters
            if self.acs.data_model.is_parameter_present(name):
                path = self.acs.data_model.get_parameter(name).path
                request.ParameterNames.string.append(path)
        request.ParameterNames.arrayType = \
            'xsd:string[%d]' % len(request.ParameterNames.string)

        return AcsMsgAndTransition(request, self.done_transition)

    def state_description(self) -> str:
        return 'Getting transient read-only parameters'


class WaitGetTransientParametersState(EnodebAcsState):
    """
    Periodically read eNodeB status. Note: keep frequency low to avoid
    backing up large numbers of read operations if enodebd is busy
    """

    def __init__(
            self,
            acs: EnodebAcsStateMachine,
            when_get: str,
            when_get_obj_params: str,
            when_delete: str,
            when_add: str,
            when_set: str,
            when_skip: str,
    ):
        super().__init__()
        self.acs = acs
        self.done_transition = when_get
        self.get_obj_params_transition = when_get_obj_params
        self.rm_obj_transition = when_delete
        self.add_obj_transition = when_add
        self.set_transition = when_set
        self.skip_transition = when_skip

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        if not isinstance(message, models.GetParameterValuesResponse):
            return AcsReadMsgResult(False, None)
        # Current values of the fetched parameters
        name_to_val = parse_get_parameter_values_response(
            self.acs.data_model,
            message,
        )
        logger.debug('Fetched Transient Params: %s', str(name_to_val))

        # Update device configuration
        for name in name_to_val:
            magma_val = \
                self.acs.data_model.transform_for_magma(
                    name,
                    name_to_val[name],
                )
            self.acs.device_cfg.set_parameter(name, magma_val)

        return AcsReadMsgResult(True, self.get_next_state())

    def get_next_state(self) -> str:
        should_get_params = \
            len(
                get_params_to_get(
                    self.acs.device_cfg,
                    self.acs.data_model,
                ),
            ) > 0
        if should_get_params:
            return self.done_transition
        should_get_obj_params = \
            len(
                get_object_params_to_get(
                    self.acs.desired_cfg,
                    self.acs.device_cfg,
                    self.acs.data_model,
                ),
            ) > 0
        if should_get_obj_params:
            return self.get_obj_params_transition
        elif len(
            get_all_objects_to_delete(
                self.acs.desired_cfg,
                self.acs.device_cfg,
            ),
        ) > 0:
            return self.rm_obj_transition
        elif len(
            get_all_objects_to_add(
                self.acs.desired_cfg,
                self.acs.device_cfg,
            ),
        ) > 0:
            return self.add_obj_transition
        return self.skip_transition

    def state_description(self) -> str:
        return 'Getting transient read-only parameters'


class GetParametersState(EnodebAcsState):
    """
    Get the value of most parameters of the eNB that are defined in the data
    model. Object parameters are excluded.
    """

    def __init__(
        self,
        acs: EnodebAcsStateMachine,
        when_done: str,
        request_all_params: bool = False,
    ):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done
        # Set to True if we want to request values of all parameters, even if
        # the ACS state machine already has recorded values of them.
        self.request_all_params = request_all_params

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        """
        It's expected that we transition into this state right after receiving
        an Inform message and replying with an InformResponse. At that point,
        the eNB sends an empty HTTP request (aka DummyInput) to initiate the
        rest of the provisioning process
        """
        if not isinstance(message, models.DummyInput):
            return AcsReadMsgResult(False, None)
        return AcsReadMsgResult(True, None)

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        """
        Respond with GetParameterValuesRequest

        Get the values of all parameters defined in the data model.
        Also check which addable objects are present, and what the values of
        parameters for those objects are.
        """

        # Get the names of regular parameters
        names = get_params_to_get(
            self.acs.device_cfg, self.acs.data_model,
            self.request_all_params,
        )

        # Generate the request
        request = models.GetParameterValues()
        request.ParameterNames = models.ParameterNames()
        request.ParameterNames.arrayType = 'xsd:string[%d]' \
                                           % len(names)
        request.ParameterNames.string = []
        for name in names:
            path = self.acs.data_model.get_parameter(name).path
            if path is not InvalidTrParamPath:
                # Only get data elements backed by tr69 path
                request.ParameterNames.string.append(path)

        return AcsMsgAndTransition(request, self.done_transition)

    def state_description(self) -> str:
        return 'Getting non-object parameters'


class WaitGetParametersState(EnodebAcsState):
    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        """ Process GetParameterValuesResponse """
        if not isinstance(message, models.GetParameterValuesResponse):
            return AcsReadMsgResult(False, None)
        name_to_val = parse_get_parameter_values_response(
            self.acs.data_model,
            message,
        )
        logger.debug('Received CPE parameter values: %s', str(name_to_val))
        for name, val in name_to_val.items():
            magma_val = self.acs.data_model.transform_for_magma(name, val)
            self.acs.device_cfg.set_parameter(name, magma_val)
        return AcsReadMsgResult(True, self.done_transition)

    def state_description(self) -> str:
        return 'Getting non-object parameters'


class GetObjectParametersState(EnodebAcsState):
    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        """ Respond with GetParameterValuesRequest """
        names = get_object_params_to_get(
            self.acs.desired_cfg,
            self.acs.device_cfg,
            self.acs.data_model,
        )

        # Generate the request
        request = models.GetParameterValues()
        request.ParameterNames = models.ParameterNames()
        request.ParameterNames.arrayType = 'xsd:string[%d]' \
                                           % len(names)
        request.ParameterNames.string = []
        for name in names:
            path = self.acs.data_model.get_parameter(name).path
            request.ParameterNames.string.append(path)

        return AcsMsgAndTransition(request, self.done_transition)

    def state_description(self) -> str:
        return 'Getting object parameters'


class WaitGetObjectParametersState(EnodebAcsState):
    def __init__(
        self,
        acs: EnodebAcsStateMachine,
        when_delete: str,
        when_add: str,
        when_set: str,
        when_skip: str,
    ):
        super().__init__()
        self.acs = acs
        self.rm_obj_transition = when_delete
        self.add_obj_transition = when_add
        self.set_params_transition = when_set
        self.skip_transition = when_skip

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        """ Process GetParameterValuesResponse """
        if not isinstance(message, models.GetParameterValuesResponse):
            return AcsReadMsgResult(False, None)

        path_to_val = {}
        if hasattr(message.ParameterList, 'ParameterValueStruct') and \
                message.ParameterList.ParameterValueStruct is not None:
            for param_value_struct in message.ParameterList.ParameterValueStruct:
                path_to_val[param_value_struct.Name] = \
                    param_value_struct.Value.Data
        logger.debug('Received object parameters: %s', str(path_to_val))

        # Number of PLMN objects reported can be incorrect. Let's count them
        num_plmns = 0
        obj_to_params = self.acs.data_model.get_numbered_param_names()
        while True:
            obj_name = ParameterName.PLMN_N % (num_plmns + 1)
            if obj_name not in obj_to_params or len(obj_to_params[obj_name]) == 0:
                logger.warning(
                    "eNB has PLMN %s but not defined in model",
                    obj_name,
                )
                break
            param_name_list = obj_to_params[obj_name]
            obj_path = self.acs.data_model.get_parameter(param_name_list[0]).path
            if obj_path not in path_to_val:
                break
            if not self.acs.device_cfg.has_object(obj_name):
                self.acs.device_cfg.add_object(obj_name)
            num_plmns += 1
            for name in param_name_list:
                path = self.acs.data_model.get_parameter(name).path
                value = path_to_val[path]
                magma_val = \
                    self.acs.data_model.transform_for_magma(name, value)
                self.acs.device_cfg.set_parameter_for_object(
                    name, magma_val,
                    obj_name,
                )
        num_plmns_reported = \
                int(self.acs.device_cfg.get_parameter(ParameterName.NUM_PLMNS))
        if num_plmns != num_plmns_reported:
            logger.warning(
                "eNB reported %d PLMNs but found %d",
                num_plmns_reported, num_plmns,
            )
            self.acs.device_cfg.set_parameter(
                ParameterName.NUM_PLMNS,
                num_plmns,
            )

        # Now we can have the desired state
        if self.acs.desired_cfg is None:
            self.acs.desired_cfg = build_desired_config(
                self.acs.mconfig,
                self.acs.service_config,
                self.acs.device_cfg,
                self.acs.data_model,
                self.acs.config_postprocessor,
            )

        if len(
            get_all_objects_to_delete(
                self.acs.desired_cfg,
                self.acs.device_cfg,
            ),
        ) > 0:
            return AcsReadMsgResult(True, self.rm_obj_transition)
        elif len(
            get_all_objects_to_add(
                self.acs.desired_cfg,
                self.acs.device_cfg,
            ),
        ) > 0:
            return AcsReadMsgResult(True, self.add_obj_transition)
        elif len(
            get_all_param_values_to_set(
                self.acs.desired_cfg,
                self.acs.device_cfg,
                self.acs.data_model,
            ),
        ) > 0:
            return AcsReadMsgResult(True, self.set_params_transition)
        return AcsReadMsgResult(True, self.skip_transition)

    def state_description(self) -> str:
        return 'Getting object parameters'


class DeleteObjectsState(EnodebAcsState):
    def __init__(
        self,
        acs: EnodebAcsStateMachine,
        when_add: str,
        when_skip: str,
    ):
        super().__init__()
        self.acs = acs
        self.deleted_param = None
        self.add_obj_transition = when_add
        self.skip_transition = when_skip

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        """
        Send DeleteObject message to TR-069 and poll for response(s).
        Input:
            - Object name (string)
        """
        request = models.DeleteObject()
        self.deleted_param = get_all_objects_to_delete(
            self.acs.desired_cfg,
            self.acs.device_cfg,
        )[0]
        request.ObjectName = \
            self.acs.data_model.get_parameter(self.deleted_param).path
        return AcsMsgAndTransition(request, None)

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        """
        Send DeleteObject message to TR-069 and poll for response(s).
        Input:
            - Object name (string)
        """
        if type(message) == models.DeleteObjectResponse:
            if message.Status != 0:
                raise Tr069Error(
                    'Received DeleteObjectResponse with '
                    'Status=%d' % message.Status,
                )
        elif type(message) == models.Fault:
            raise Tr069Error(
                'Received Fault in response to DeleteObject '
                '(faultstring = %s)' % message.FaultString,
            )
        else:
            return AcsReadMsgResult(False, None)

        self.acs.device_cfg.delete_object(self.deleted_param)
        obj_list_to_delete = get_all_objects_to_delete(
            self.acs.desired_cfg,
            self.acs.device_cfg,
        )
        if len(obj_list_to_delete) > 0:
            return AcsReadMsgResult(True, None)
        if len(
            get_all_objects_to_add(
                self.acs.desired_cfg,
                self.acs.device_cfg,
            ),
        ) == 0:
            return AcsReadMsgResult(True, self.skip_transition)
        return AcsReadMsgResult(True, self.add_obj_transition)

    def state_description(self) -> str:
        return 'Deleting objects'


class AddObjectsState(EnodebAcsState):
    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done
        self.added_param = None

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        request = models.AddObject()
        self.added_param = get_all_objects_to_add(
            self.acs.desired_cfg,
            self.acs.device_cfg,
        )[0]
        desired_param = self.acs.data_model.get_parameter(self.added_param)
        desired_path = desired_param.path
        path_parts = desired_path.split('.')
        # If adding enumerated object, ie. XX.N. we should add it to the
        # parent object XX. so strip the index
        if len(path_parts) > 2 and \
                path_parts[-1] == '' and path_parts[-2].isnumeric():
            logger.debug('Stripping index from path=%s', desired_path)
            desired_path = '.'.join(path_parts[:-2]) + '.'
        request.ObjectName = desired_path
        return AcsMsgAndTransition(request, None)

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        if type(message) == models.AddObjectResponse:
            if message.Status != 0:
                raise Tr069Error(
                    'Received AddObjectResponse with '
                    'Status=%d' % message.Status,
                )
        elif type(message) == models.Fault:
            raise Tr069Error(
                'Received Fault in response to AddObject '
                '(faultstring = %s)' % message.FaultString,
            )
        else:
            return AcsReadMsgResult(False, None)
        instance_n = message.InstanceNumber
        self.acs.device_cfg.add_object(self.added_param % instance_n)
        obj_list_to_add = get_all_objects_to_add(
            self.acs.desired_cfg,
            self.acs.device_cfg,
        )
        if len(obj_list_to_add) > 0:
            return AcsReadMsgResult(True, None)
        return AcsReadMsgResult(True, self.done_transition)

    def state_description(self) -> str:
        return 'Adding objects'


class SetParameterValuesState(EnodebAcsState):
    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        request = models.SetParameterValues()
        request.ParameterList = models.ParameterValueList()
        param_values = get_all_param_values_to_set(
            self.acs.desired_cfg,
            self.acs.device_cfg,
            self.acs.data_model,
        )
        request.ParameterList.arrayType = 'cwmp:ParameterValueStruct[%d]' \
                                           % len(param_values)
        request.ParameterList.ParameterValueStruct = []
        logger.debug(
            'Sending TR069 request to set CPE parameter values: %s',
            str(param_values),
        )
        # TODO: Match key response when we support having multiple outstanding
        # calls.
        if self.acs.has_version_key:
            request.ParameterKey = models.ParameterKeyType()
            request.ParameterKey.Data =\
                "SetParameter-{:10.0f}".format(self.acs.parameter_version_key)
            request.ParameterKey.type = 'xsd:string'

        for name, value in param_values.items():
            param_info = self.acs.data_model.get_parameter(name)
            type_ = param_info.type
            name_value = models.ParameterValueStruct()
            name_value.Value = models.anySimpleType()
            name_value.Name = param_info.path
            enb_value = self.acs.data_model.transform_for_enb(name, value)
            if type_ in ('int', 'unsignedInt'):
                name_value.Value.type = 'xsd:%s' % type_
                name_value.Value.Data = str(enb_value)
            elif type_ == 'boolean':
                # Boolean values have integral representations in spec
                name_value.Value.type = 'xsd:boolean'
                name_value.Value.Data = str(int(enb_value))
            elif type_ == 'string':
                name_value.Value.type = 'xsd:string'
                name_value.Value.Data = str(enb_value)
            else:
                raise Tr069Error(
                    'Unsupported type for %s: %s' %
                    (name, type_),
                )
            if param_info.is_invasive:
                self.acs.are_invasive_changes_applied = False
            request.ParameterList.ParameterValueStruct.append(name_value)

        return AcsMsgAndTransition(request, self.done_transition)

    def state_description(self) -> str:
        return 'Setting parameter values'


class SetParameterValuesNotAdminState(EnodebAcsState):
    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        request = models.SetParameterValues()
        request.ParameterList = models.ParameterValueList()
        param_values = get_all_param_values_to_set(
            self.acs.desired_cfg,
            self.acs.device_cfg,
            self.acs.data_model,
            exclude_admin=True,
        )
        request.ParameterList.arrayType = 'cwmp:ParameterValueStruct[%d]' \
                                          % len(param_values)
        request.ParameterList.ParameterValueStruct = []
        logger.debug(
            'Sending TR069 request to set CPE parameter values: %s',
            str(param_values),
        )
        for name, value in param_values.items():
            param_info = self.acs.data_model.get_parameter(name)
            type_ = param_info.type
            name_value = models.ParameterValueStruct()
            name_value.Value = models.anySimpleType()
            name_value.Name = param_info.path
            enb_value = self.acs.data_model.transform_for_enb(name, value)
            if type_ in ('int', 'unsignedInt'):
                name_value.Value.type = 'xsd:%s' % type_
                name_value.Value.Data = str(enb_value)
            elif type_ == 'boolean':
                # Boolean values have integral representations in spec
                name_value.Value.type = 'xsd:boolean'
                name_value.Value.Data = str(int(enb_value))
            elif type_ == 'string':
                name_value.Value.type = 'xsd:string'
                name_value.Value.Data = str(enb_value)
            else:
                raise Tr069Error(
                    'Unsupported type for %s: %s' %
                    (name, type_),
                )
            if param_info.is_invasive:
                self.acs.are_invasive_changes_applied = False
            request.ParameterList.ParameterValueStruct.append(name_value)

        return AcsMsgAndTransition(request, self.done_transition)

    def state_description(self) -> str:
        return 'Setting parameter values excluding Admin Enable'


class WaitSetParameterValuesState(EnodebAcsState):
    def __init__(
        self,
        acs: EnodebAcsStateMachine,
        when_done: str,
        when_apply_invasive: str,
        status_non_zero_allowed: bool = False,
    ):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done
        self.apply_invasive_transition = when_apply_invasive
        # Set Params can legally return zero and non zero status
        # Per tr-196, if there are errors the method should return a fault.
        # Make flag optional to compensate for existing radios returning non
        # zero on error.
        self.status_non_zero_allowed = status_non_zero_allowed

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        if type(message) == models.SetParameterValuesResponse:
            if not self.status_non_zero_allowed:
                if message.Status != 0:
                    raise Tr069Error(
                        'Received SetParameterValuesResponse with '
                        'Status=%d' % message.Status,
                    )
            self._mark_as_configured()

            metrics.STAT_ENODEB_LAST_CONFIGURED.labels(
                serial_number=self.acs.device_cfg.get_parameter("Serial number"),
                ip_address=self.acs.device_cfg.get_parameter("ip_address"),
                gps_lat=self.acs.device_cfg.get_parameter("GPS lat"),
                gps_lon=self.acs.device_cfg.get_parameter("GPS long")
            ).set(int(time.time()))

            if not self.acs.are_invasive_changes_applied:
                return AcsReadMsgResult(True, self.apply_invasive_transition)
            return AcsReadMsgResult(True, self.done_transition)
        elif type(message) == models.Fault:
            logger.error(
                'Received Fault in response to SetParameterValues, '
                'Code (%s), Message (%s)', message.FaultCode,
                message.FaultString,
            )
            if message.SetParameterValuesFault is not None:
                for fault in message.SetParameterValuesFault:
                    logger.error(
                        'SetParameterValuesFault Param: %s, '
                        'Code: %s, String: %s', fault.ParameterName,
                        fault.FaultCode, fault.FaultString,
                    )
        return AcsReadMsgResult(False, None)

    def _mark_as_configured(self) -> None:
        """
        A successful attempt at setting parameter values means that we need to
        update what we think the eNB's configuration is to match what we just
        set the parameter values to.
        """
        # Values of parameters
        name_to_val = get_param_values_to_set(
            self.acs.desired_cfg,
            self.acs.device_cfg,
            self.acs.data_model,
        )
        for name, val in name_to_val.items():
            magma_val = self.acs.data_model.transform_for_magma(name, val)
            self.acs.device_cfg.set_parameter(name, magma_val)

        # Values of object parameters
        obj_to_name_to_val = get_obj_param_values_to_set(
            self.acs.desired_cfg,
            self.acs.device_cfg,
            self.acs.data_model,
        )
        for obj_name, name_to_val in obj_to_name_to_val.items():
            for name, val in name_to_val.items():
                logger.debug(
                    'Set obj: %s, name: %s, val: %s', str(obj_name),
                    str(name), str(val),
                )
                magma_val = self.acs.data_model.transform_for_magma(name, val)
                self.acs.device_cfg.set_parameter_for_object(
                    name, magma_val,
                    obj_name,
                )
        logger.info('Successfully configured CPE parameters!')

    def state_description(self) -> str:
        return 'Setting parameter values'


class EndSessionState(EnodebAcsState):
    """ To end a TR-069 session, send an empty HTTP response """

    def __init__(self, acs: EnodebAcsStateMachine):
        super().__init__()
        self.acs = acs

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        """
        No message is expected after enodebd sends the eNodeB
        an empty HTTP response.

        If a device sends an empty HTTP request, we can just
        ignore it and send another empty response.
        """
        if isinstance(message, models.DummyInput):
            return AcsReadMsgResult(True, None)
        return AcsReadMsgResult(False, None)

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        request = models.DummyInput()
        return AcsMsgAndTransition(request, None)

    def state_description(self) -> str:
        return 'Completed provisioning eNB. Awaiting new Inform.'


class EnbSendRebootState(EnodebAcsState):
    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done
        self.prev_msg_was_inform = False

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        """
        This state can be transitioned into through user command.
        All messages received by enodebd will be ignored in this state.
        """
        if self.prev_msg_was_inform \
                and not isinstance(message, models.DummyInput):
            return AcsReadMsgResult(False, None)
        elif isinstance(message, models.Inform):
            self.prev_msg_was_inform = True
            process_inform_message(
                message, self.acs.data_model,
                self.acs.device_cfg,
            )
            return AcsReadMsgResult(True, None)
        self.prev_msg_was_inform = False
        return AcsReadMsgResult(True, None)

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        if self.prev_msg_was_inform:
            response = models.InformResponse()
            # Set maxEnvelopes to 1, as per TR-069 spec
            response.MaxEnvelopes = 1
            return AcsMsgAndTransition(response, None)
        logger.info('Sending reboot request to eNB')
        request = models.Reboot()
        request.CommandKey = ''
        self.acs.are_invasive_changes_applied = True
        return AcsMsgAndTransition(request, self.done_transition)

    def state_description(self) -> str:
        return 'Rebooting eNB'


class SendRebootState(EnodebAcsState):
    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done
        self.prev_msg_was_inform = False

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        """
        This state can be transitioned into through user command.
        All messages received by enodebd will be ignored in this state.
        """
        if self.prev_msg_was_inform \
                and not isinstance(message, models.DummyInput):
            return AcsReadMsgResult(False, None)
        elif isinstance(message, models.Inform):
            self.prev_msg_was_inform = True
            process_inform_message(
                message, self.acs.data_model,
                self.acs.device_cfg,
            )
            return AcsReadMsgResult(True, None)
        self.prev_msg_was_inform = False
        return AcsReadMsgResult(True, None)

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        if self.prev_msg_was_inform:
            response = models.InformResponse()
            # Set maxEnvelopes to 1, as per TR-069 spec
            response.MaxEnvelopes = 1
            return AcsMsgAndTransition(response, None)
        logger.info('Sending reboot request to eNB')
        request = models.Reboot()
        request.CommandKey = ''
        return AcsMsgAndTransition(request, self.done_transition)

    def state_description(self) -> str:
        return 'Rebooting eNB'


class WaitRebootResponseState(EnodebAcsState):
    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        if not isinstance(message, models.RebootResponse):
            return AcsReadMsgResult(False, None)
        return AcsReadMsgResult(True, None)

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        """ Reply with empty message """
        return AcsMsgAndTransition(models.DummyInput(), self.done_transition)

    def state_description(self) -> str:
        return 'Rebooting eNB'


class WaitInformMRebootState(EnodebAcsState):
    """
    After sending a reboot request, we expect an Inform request with a
    specific 'inform event code'
    """

    # Time to wait for eNodeB reboot. The measured time
    # (on BaiCells indoor eNodeB)
    # is ~110secs, so add healthy padding on top of this.
    REBOOT_TIMEOUT = 300  # In seconds
    # We expect that the Inform we receive tells us the eNB has rebooted
    INFORM_EVENT_CODE = 'M Reboot'

    def __init__(
        self,
        acs: EnodebAcsStateMachine,
        when_done: str,
        when_timeout: str,
    ):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done
        self.timeout_transition = when_timeout
        self.timeout_timer = None
        self.timer_handle = None

    def enter(self):
        self.timeout_timer = StateMachineTimer(self.REBOOT_TIMEOUT)

        def check_timer() -> None:
            if self.timeout_timer.is_done():
                self.acs.transition(self.timeout_transition)
                raise Tr069Error(
                    'Did not receive Inform response after '
                    'rebooting',
                )

        self.timer_handle = \
            self.acs.event_loop.call_later(
                self.REBOOT_TIMEOUT,
                check_timer,
            )

    def exit(self):
        self.timer_handle.cancel()
        self.timeout_timer = None

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        if not isinstance(message, models.Inform):
            return AcsReadMsgResult(False, None)
        if not does_inform_have_event(message, self.INFORM_EVENT_CODE):
            raise Tr069Error(
                'Did not receive M Reboot event code in '
                'Inform',
            )
        process_inform_message(
            message, self.acs.data_model,
            self.acs.device_cfg,
        )
        return AcsReadMsgResult(True, self.done_transition)

    def state_description(self) -> str:
        return 'Waiting for M Reboot code from Inform'


class WaitRebootDelayState(EnodebAcsState):
    """
    After receiving the Inform notifying us that the eNodeB has successfully
    rebooted, wait a short duration to prevent unspecified race conditions
    that may occur w.r.t reboot
    """

    # Short delay timer to prevent race conditions w.r.t. reboot
    SHORT_CONFIG_DELAY = 10

    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done
        self.config_timer = None
        self.timer_handle = None

    def enter(self):
        self.config_timer = StateMachineTimer(self.SHORT_CONFIG_DELAY)

        def check_timer() -> None:
            if self.config_timer.is_done():
                self.acs.transition(self.done_transition)

        self.timer_handle = \
            self.acs.event_loop.call_later(
                self.SHORT_CONFIG_DELAY,
                check_timer,
            )

    def exit(self):
        self.timer_handle.cancel()
        self.config_timer = None

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        return AcsReadMsgResult(True, None)

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        return AcsMsgAndTransition(models.DummyInput(), None)

    def state_description(self) -> str:
        return 'Waiting after eNB reboot to prevent race conditions'


class DownloadState(EnodebAcsState):
    """
    The eNB handler will enter this state when firmware version is older than desired version.
    """

    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done

    def get_msg(self, message: Any) -> AcsMsgAndTransition:

        print("ACS Device CFG")
        print(self.acs.device_cfg._param_to_value)

        request = models.Download()
        request.CommandKey = "20220206215200"
        request.FileType = "1 Firmware Upgrade Image"
        request.URL = "http://18.116.99.179/firmware/Qproject_TEST3918_2102241222.ffw"
        request.Username = ""
        request.Password = ""
        request.FileSize = 57208579
        request.TargetFileName = "Qproject_TEST3918_2102241222.ffw"
        request.DelaySeconds = 0
        request.SuccessURL = ""
        request.FailureURL = ""
        return AcsMsgAndTransition(request, self.done_transition)

    def state_description(self) -> str:
        return 'Upgrade the firmware the desired version'

class WaitDownloadResponseState(EnodebAcsState):
    """
    The eNB handler will enter this state after the Download command sent.
    """

    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done
        
    def read_msg(self, message: Any) -> AcsReadMsgResult:
        if not isinstance(message, models.DownloadResponse):
            return AcsReadMsgResult(False, None)
        return AcsReadMsgResult(True, None)

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        """ Reply with empty message """
        logger.info("Received Download Response from eNodeB")
        return AcsMsgAndTransition(models.DummyInput(), self.done_transition)

    def state_description(self) -> str:
        return "Wait DownloadResponse message"

class WaitInformTransferCompleteState(EnodebAcsState):
    """
    The eNB handler will enter this state after firmware upgraded and rebooted
    """

    REBOOT_TIMEOUT = 300 # In seconds
    INFORM_EVENT_CODE = "7 TRANSFER COMPLETE"
    PREIODIC_EVENT_CODE = "2 PERIODIC"

    def __init__(self, acs: EnodebAcsStateMachine, when_done: str, when_periodic: str, when_timeout: str):
        super().__init__()
        self.acs = acs
        self.done_transition = when_done
        self.periodic_update_transition = when_periodic
        self.timeout_transition = when_timeout
        self.timeout_timer = None
        self.timer_handle = None
    
    def enter(self):
        print("Get into the TransferComplete State")
        self.timeout_timer = StateMachineTimer(self.REBOOT_TIMEOUT)

        def check_timer() -> None:
            if self.timeout_timer.is_done():
                self.acs.transition(self.timeout_transition)
                raise Tr069Error("Didn't receive Inform response after rebooting")

        self.timer_handle = self.acs.event_loop.call_later(
            self.REBOOT_TIMEOUT,
            check_timer,
        )

    def exit(self):
        self.timer_handle.cancel()
        self.timeout_timer = None

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        return AcsMsgAndTransition(models.DummyInput(), None)

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        if not isinstance(message, models.Inform):
            return AcsReadMsgResult(False, None)
        if does_inform_have_event(message, self.PREIODIC_EVENT_CODE):
            logger.info("Receive Periodic update from enodeb")
            return AcsReadMsgResult(True, self.periodic_update_transition)
        if does_inform_have_event(message, self.INFORM_EVENT_CODE):
            logger.info("Receive Transfer complete")
            return AcsReadMsgResult(True, self.done_transition)

        # Unhandled situation
        return AcsReadMsgResult(False, None)

    def state_description(self) -> str:
        return "Wait DownloadResponse message"

class ErrorState(EnodebAcsState):
    """
    The eNB handler will enter this state when an unhandled Fault is received.

    If the inform_transition_target constructor parameter is non-null, this
    state will attempt to autoremediate by transitioning to the specified
    target state when an Inform is received.
    """

    def __init__(
        self, acs: EnodebAcsStateMachine,
        inform_transition_target: Optional[str] = None,
    ):
        super().__init__()
        self.acs = acs
        self.inform_transition_target = inform_transition_target

    def read_msg(self, message: Any) -> AcsReadMsgResult:
        return AcsReadMsgResult(True, None)

    def get_msg(self, message: Any) -> AcsMsgAndTransition:
        if not self.inform_transition_target:
            return AcsMsgAndTransition(models.DummyInput(), None)

        if isinstance(message, models.Inform):
            return AcsMsgAndTransition(
                models.DummyInput(),
                self.inform_transition_target,
            )
        return AcsMsgAndTransition(models.DummyInput(), None)

    def state_description(self) -> str:
        return 'Error state - awaiting manual restart of enodebd service or ' \
               'an Inform to be received from the eNB'