#
# Copyright 2016 the original author or 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.
#

"""
Base OLT State machine class
"""
import time

from structlog import get_logger
from twisted.internet import reactor, task
from voltha.adapters.microsemi.PAS5211 import PAS5211MsgGetProtocolVersion, PAS5211MsgGetOltVersion

log = get_logger()

class States(object):
    DISCONNECTED = 0
    FETCH_VERSION = 1
    CONNECTED = 2

# TODO convert to scapy automata
class State(object):

    def __init__(self):
        pass

    """
    Attempt an operation towards the OLT
    """
    def run(self):
        raise NotImplementedError()

    """
    Dictates which state to transtion to.
    Predicated on the run operation to be successful.
    """
    def transition(self):
        raise NotImplementedError()

    """
    Returns the current state name
    """
    def state(self):
        raise NotImplementedError()

    """
    Returns any useful information for the given State
    """
    def value(self):
        raise NotImplementedError()

    """
    Sends a message to this olt
    """
    def send_msg(self, msg):
        raise NotImplementedError()

    """
    Disconnected an OLT.
    """
    def disconnect(self):
        raise NotImplementedError()

    """
    Indicates whether to abandon trying to connect.
    """
    def abandon(self):
        raise  NotImplementedError()

"""
Represents an OLT in disconnected or pre init state.
"""
class Disconnected(State):

    def __init__(self, pas_comm, retry=3):
        self.comm = pas_comm
        self.completed = False
        self.packet = None
        self.retry = retry
        self.attempt = 1

    def run(self):
        self.packet = self.comm.communicate(PAS5211MsgGetProtocolVersion())
        if self.packet is not None:
            self.packet.show()
            self.completed = True
        else:
            if self.attempt <= self.retry:
                time.sleep(self.attempt)
                self.attempt += 1
        return self.completed

    def transition(self):
        if self.completed:
            return Fetch_Version(self.comm)
        else:
            return self

    def state(self):
        return States.DISCONNECTED

    def value(self):
        # TODO return a nicer value than the packet.
        return self.packet

    def send_msg(self, msg):
        raise NotImplementedError()

    def disconnect(self):
        pass

    def abandon(self):
        return self.attempt > self.retry

"""
Fetches the OLT version
"""
class Fetch_Version(State):
    def __init__(self, pas_comm):
        self.comm = pas_comm
        self.completed = False
        self.packet = None

    def run(self):
        self.packet = self.comm.communicate(PAS5211MsgGetOltVersion())
        if self.packet is not None:
            self.packet.show()
            self.completed = True
        return self.completed

    def transition(self):
        if self.completed:
            return Connected(self.comm)
        else:
            return self

    def state(self):
        return States.FETCH_VERSION

    def value(self):
        # TODO return a nicer value than the packet.
        return self.packet

    def send_msg(self, msg):
        raise NotImplementedError()

    def disconnect(self):
        raise NotImplementedError()

    def abandon(self):
        return False


"""
OLT is in connected State
"""
class Connected(State):
    def __init__(self, pas_comm):
        self.comm = pas_comm
        self.completed = False
        self.packet = None
        self.scheduled = False
        self.scheduledTask = task.LoopingCall(self.keepalive)

    def run(self):
        if not self.scheduled:
            self.scheduled = True
            self.scheduledTask.start(1.0)

    def transition(self):
        if self.completed:
            return Disconnected(self.comm)
        else:
            return self

    def state(self):
        return States.CONNECTED

    def value(self):
        # TODO return a nicer value than the packet.
        return self.packet

    def send_msg(self, msg):
        return self.comm.communicate(msg)

    def keepalive(self):
        if self.completed:
            log.info('OLT has been disconnected')
            return
        self.packet = self.comm.communicate(PAS5211MsgGetOltVersion())
        if self.packet is None:
            self.completed = True

    def disconnect(self):
        print "Disconnecting OLT"
        if self.scheduled:
            self.completed = True
            self.scheduledTask.stop()
        return self.transition()

    def abandon(self):
        return False