from __future__ import print_function
from concurrent import futures
from subprocess import Popen, DEVNULL
import argparse
import sys
import time
import os
import grpc
import logging
from typing import Dict
import grpc, logging
from prometheus_client import Counter, Histogram
from common.orm.Database import Database
from l3_attackmitigator.proto.context_pb2 import Empty
from l3_attackmitigator.proto.l3_attackmitigator_pb2 import (
    EmptyMitigator
)
from l3_attackmitigator.proto.l3_attackmitigator_pb2_grpc import (
    L3AttackmitigatorServicer,
    add_L3AttackmitigatorServicer_to_server
)

LOGGER = logging.getLogger(__name__)

LAST_VALUE = -1


class l3_attackmitigatorServiceServicerImpl(L3AttackmitigatorServicer):

    def __init__(self):
        LOGGER.debug("Creating Servicer...")
    
    class Mitigator(L3AttackmitigatorServicer):
        def send_output(self, request, context):
            # SEND CONFIDENCE TO MITIGATION SERVER
            logging.debug("")
            print("Server received mitigation values...", request.confidence)
            LAST_VALUE = request.confidence
            LAST_TAG = request.tag
            # RETURN OK TO THE CALLER
            return EmptyMitigator(
                message=f"OK, received values: {LAST_TAG} with confidence {LAST_VALUE}."
            )

        def get_mitigation(self, request, context):
            # GET OR PERFORM MITIGATION STRATEGY
            logging.debug("")
            print("Returing mitigation strategy...")
            k = LAST_VALUE * 2
            return EmptyMitigator(
                message=f"Mitigation with double confidence = {k}"
            )


    def serve(self):
        server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
        add_L3AttackmitigatorServicer_to_server(self.Mitigator(), server)
        server.add_insecure_port('[::]:10002')
        server.start()
        print('Server Started')
        server.wait_for_termination()
        print('Server Terminated')

    def setupl3_attackmitigator(self):
        logging.basicConfig()
        self.serve()



    
