#
# Copyright 2017 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.
#

"""
The gRPC client layer for the OpenFlow agent
"""
from Queue import Queue, Empty
import os

from grpc import StatusCode
from grpc._channel import _Rendezvous
from structlog import get_logger
from twisted.internet import reactor
from twisted.internet import threads
from twisted.internet.defer import inlineCallbacks, returnValue, DeferredQueue

from protos.voltha_pb2 import ID, VolthaLocalServiceStub, FlowTableUpdate, MeterModUpdate, \
    FlowGroupTableUpdate, PacketOut
from protos.logical_device_pb2 import LogicalPortId
from google.protobuf import empty_pb2


class GrpcClient(object):

    def __init__(self, connection_manager, channel, grpc_timeout):

        self.log = get_logger()

        self.connection_manager = connection_manager
        self.channel = channel
        self.grpc_timeout = grpc_timeout
        self.local_stub = VolthaLocalServiceStub(channel)

        self.stopped = False

        self.packet_out_queue = Queue()  # queue to send out PacketOut msgs
        self.packet_in_queue = DeferredQueue()  # queue to receive PacketIn
        self.change_event_queue = DeferredQueue()  # queue change events

    def start(self):
        self.log.debug('starting', grpc_timeout=self.grpc_timeout)
        self.start_packet_out_stream()
        self.start_packet_in_stream()
        self.start_change_event_in_stream()
        reactor.callLater(0, self.packet_in_forwarder_loop)
        reactor.callLater(0, self.change_event_processing_loop)
        self.log.info('started')
        return self

    def stop(self):
        self.log.debug('stopping')
        self.stopped = True
        self.log.info('stopped')

    def start_packet_out_stream(self):

        def packet_generator():
            while 1:
                try:
                    packet = self.packet_out_queue.get(block=True, timeout=1.0)
                except Empty:
                    if self.stopped:
                        return
                else:
                    yield packet

        def stream_packets_out():
            generator = packet_generator()
            try:
                self.local_stub.StreamPacketsOut(generator)
            except _Rendezvous, e:
                self.log.error('grpc-exception', status=e.code())
                if e.code() == StatusCode.UNAVAILABLE:
                    os.system("kill -15 {}".format(os.getpid()))

        reactor.callInThread(stream_packets_out)

    def start_packet_in_stream(self):

        def receive_packet_in_stream():
            streaming_rpc_method = self.local_stub.ReceivePacketsIn
            iterator = streaming_rpc_method(empty_pb2.Empty())
            try:
                for packet_in in iterator:
                    reactor.callFromThread(self.packet_in_queue.put,
                                           packet_in)
                    self.log.debug('enqued-packet-in',
                              packet_in=packet_in,
                              queue_len=len(self.packet_in_queue.pending))
            except _Rendezvous, e:
                self.log.error('grpc-exception', status=e.code())
                if e.code() == StatusCode.UNAVAILABLE:
                    os.system("kill -15 {}".format(os.getpid()))

        reactor.callInThread(receive_packet_in_stream)

    def start_change_event_in_stream(self):

        def receive_change_events():
            streaming_rpc_method = self.local_stub.ReceiveChangeEvents
            iterator = streaming_rpc_method(empty_pb2.Empty())
            try:
                for event in iterator:
                    reactor.callFromThread(self.change_event_queue.put, event)
                    self.log.debug('enqued-change-event',
                              change_event=event,
                              queue_len=len(self.change_event_queue.pending))
            except _Rendezvous, e:
                self.log.error('grpc-exception', status=e.code())
                if e.code() == StatusCode.UNAVAILABLE:
                    os.system("kill -15 {}".format(os.getpid()))

        reactor.callInThread(receive_change_events)

    @inlineCallbacks
    def change_event_processing_loop(self):
        while True:
            try:
                event = yield self.change_event_queue.get()
                device_id = event.id
                self.connection_manager.forward_change_event(device_id, event)
            except Exception, e:
                self.log.exception('failed-in-packet-in-handler', e=e)
            if self.stopped:
                break

    @inlineCallbacks
    def packet_in_forwarder_loop(self):
        while True:
            packet_in = yield self.packet_in_queue.get()
            device_id = packet_in.id
            ofp_packet_in = packet_in.packet_in
            self.connection_manager.forward_packet_in(device_id, ofp_packet_in)
            if self.stopped:
                break

    def send_packet_out(self, device_id, packet_out):
        packet_out = PacketOut(id=device_id, packet_out=packet_out)
        self.packet_out_queue.put(packet_out)

    @inlineCallbacks
    def get_port(self, device_id, port_id):
        req = LogicalPortId(id=device_id, port_id=port_id)
        res = yield threads.deferToThread(
            self.local_stub.GetLogicalDevicePort, req, timeout=self.grpc_timeout)
        returnValue(res)

    @inlineCallbacks
    def get_port_list(self, device_id):
        req = ID(id=device_id)
        res = yield threads.deferToThread(
            self.local_stub.ListLogicalDevicePorts, req, timeout=self.grpc_timeout)
        returnValue(res.items)

    @inlineCallbacks
    def enable_port(self, device_id, port_id):
        req = LogicalPortId(
            id=device_id,
            port_id=port_id
        )
        res = yield threads.deferToThread(
            self.local_stub.EnableLogicalDevicePort, req, timeout=self.grpc_timeout)
        returnValue(res)

    @inlineCallbacks
    def disable_port(self, device_id, port_id):
        req = LogicalPortId(
            id=device_id,
            port_id=port_id
        )
        res = yield threads.deferToThread(
            self.local_stub.DisableLogicalDevicePort, req, timeout=self.grpc_timeout)
        returnValue(res)

    @inlineCallbacks
    def get_device_info(self, device_id):
        req = ID(id=device_id)
        res = yield threads.deferToThread(
            self.local_stub.GetLogicalDevice, req, timeout=self.grpc_timeout)
        returnValue(res)

    @inlineCallbacks
    def update_flow_table(self, device_id, flow_mod):
        req = FlowTableUpdate(
            id=device_id,
            flow_mod=flow_mod
        )
        res = yield threads.deferToThread(
            self.local_stub.UpdateLogicalDeviceFlowTable, req, timeout=self.grpc_timeout)
        returnValue(res)

    @inlineCallbacks
    def update_meter_mod_table(self, device_id, meter_mod):
        req = MeterModUpdate(
            id=device_id,
            meter_mod=meter_mod
        )
        res = yield threads.deferToThread(
            self.local_stub.UpdateLogicalDeviceMeterTable, req)
        returnValue(res)

    @inlineCallbacks
    def update_group_table(self, device_id, group_mod):
        req = FlowGroupTableUpdate(
            id=device_id,
            group_mod=group_mod
        )
        res = yield threads.deferToThread(
            self.local_stub.UpdateLogicalDeviceFlowGroupTable, req, timeout=self.grpc_timeout)
        returnValue(res)

    @inlineCallbacks
    def list_flows(self, device_id):
        req = ID(id=device_id)
        res = yield threads.deferToThread(
            self.local_stub.ListLogicalDeviceFlows, req, timeout=self.grpc_timeout)
        returnValue(res.items)

    @inlineCallbacks
    def list_groups(self, device_id):
        req = ID(id=device_id)
        res = yield threads.deferToThread(
            self.local_stub.ListLogicalDeviceFlowGroups, req, timeout=self.grpc_timeout)
        returnValue(res.items)

    @inlineCallbacks
    def list_ports(self, device_id):
        req = ID(id=device_id)
        res = yield threads.deferToThread(
            self.local_stub.ListLogicalDevicePorts, req, timeout=self.grpc_timeout)
        returnValue(res.items)

    @inlineCallbacks
    def list_logical_devices(self):
        res = yield threads.deferToThread(
            self.local_stub.ListLogicalDevices, empty_pb2.Empty(), timeout=self.grpc_timeout)
        returnValue(res.items)

    @inlineCallbacks
    def list_reachable_logical_devices(self):
        res = yield threads.deferToThread(
            self.local_stub.ListReachableLogicalDevices, empty_pb2.Empty(),
            timeout=self.grpc_timeout)
        returnValue(res.items)

    @inlineCallbacks
    def subscribe(self, subscriber):
        res = yield threads.deferToThread(
            self.local_stub.Subscribe, subscriber, timeout=self.grpc_timeout)
        returnValue(res)

    @inlineCallbacks
    def get_meter_stats(self, device_id):
        req = ID(id=device_id)
        res = yield threads.deferToThread(
            self.local_stub.GetMeterStatsOfLogicalDevice, req)
        returnValue(res.items)
