#
# Copyright (C) 2015-2017,  Netronome Systems, Inc.  All rights reserved.
#

import os, sys, struct, pprint, threading
from urlparse import urlparse
from contextlib import contextmanager

from RTERPCInterface import *

class RTEInterfaceConnection(object):
    def __init__(self):
        self.transport = None

        self.Design = None
        self.Counters = None
        self.Tables = None
        self.ParserValueSets = None
        self.Registers = None
        self.Meters = None
        self.TrafficClass = None
        self.Digests = None
        self.Multicast = None
        self.DebugCtl = None
        self.System = None

        self._DoConnect = None
        self._DoDisconnect = None

    def Connect(self, rpc, host, port, device_id=0, use_zlib=True, serialise_api=False):
        if rpc == 'thrift':
            from RTEThriftInterface import (Design, Counters, Tables, ParserValueSets, 
                Registers, Meters, TrafficClass, Digests, Multicast, DebugCtl, System)
            from RTEThriftInterface import RteReturnHandler, DoConnect, DoDisconnect

            global P4CounterType, RegisterType
            from  RTEThriftInterface import P4CounterType, RegisterType
            
        elif rpc == 'grpc':
            from RTEGRPCInterface import (Design, Counters, Tables, ParserValueSets, 
                Registers, Meters, TrafficClass, Digests, Multicast, DebugCtl, System)
            from RTEGRPCInterface import (RteReturnHandler, DoConnect, DoDisconnect)
        else:
            raise Exception, 'unsupported rpc: %s'%rpc

        DoConnect(self, host, port, device_id, use_zlib, serialise_api)

        self.Design = Design(self)
        self.Counters = Counters(self)
        self.Tables = Tables(self)
        self.ParserValueSets = ParserValueSets(self)
        self.Registers = Registers(self)
        self.Meters = Meters(self)
        self.TrafficClass = TrafficClass(self)
        self.Digests = Digests(self)
        self.Multicast = Multicast(self)
        self.DebugCtl = DebugCtl(self)
        self.System = System(self)
        
        self._DoConnect = DoConnect
        self._DoDisconnect = DoDisconnect
                
        status = self.Design.LoadStatus()
        if rpc == 'grpc' and status['is_loaded']:
            self.Design.RefreshP4Schema()

    def Disconnect(self):
        if self._DoDisconnect is not None:
            self._DoDisconnect(self)
                
    @contextmanager    
    def ConnectCtx(self, rpc, host, port, device_id=0, use_zlib=True, serialise_api=False):
        try:
            self.Connect(rpc, host, port, device_id, use_zlib, serialise_api)
            yield self
        finally:
            self.Disconnect()

    def Shutdown(self):
        self.System.Shutdown()
        self.Disconnect()

RTEInterface = RTEInterfaceConnection()
