import grpc
from concurrent import futures
import time
import protobufs.fortanix_pb2_grpc as pb2_grpc
import protobufs.fortanix_pb2 as pb2
import fortanix.main as main


class ConsumerServicer(pb2_grpc.ConsumerServicer):

    def __init__(self, *args, **kwargs):
        pass
    
    def CreateAccount(self, request, context):
        acct_name = request.acct_name
        result = main.create_account(acct_name=acct_name)
        resources=[]
        for ele in result:
            resources.append(pb2.Resource(
                msg=ele['msg'],
                id=ele['id'],
                name=ele['name'],
                created_at=ele['created_at'],
                type_of_resource=ele['type_of_resource']
            ))
        return pb2.Response(res=resources)
    
    def CreateAccountRole(self, request, context):
        role_name = request.role_name
        role_desc = request.role_desc
        acct_id = request.acct_id
        result = main.create_account_role(role_name=role_name,role_desc=role_desc,acct_id=acct_id)
        resources=[]
        for ele in result:
            resources.append(pb2.Resource(
                msg=ele['msg'],
                id=ele['id'],
                name=ele['name'],
                created_at=ele['created_at'],
                type_of_resource=ele['type_of_resource']
            ))
        return pb2.Response(res=resources)
    
    def CreateGroup(self, request, context):
        group_name = request.group_name
        group_desc = request.group_desc
        acct_id = request.acct_id
        result = main.create_group(group_name=group_name,group_desc=group_desc,acct_id=acct_id)
        resources=[]
        for ele in result:
            resources.append(pb2.Resource(
                msg=ele['msg'],
                id=ele['id'],
                name=ele['name'],
                created_at=ele['created_at'],
                type_of_resource=ele['type_of_resource']
            ))
        return pb2.Response(res=resources)
    
    def CreateGroupRole(self, request, context):
        role_name = request.role_name
        role_desc = request.role_desc
        acct_id = request.acct_id
        result = main.create_group_role(role_name=role_name,role_desc=role_desc,acct_id=acct_id)
        resources=[]
        for ele in result:
            resources.append(pb2.Resource(
                msg=ele['msg'],
                id=ele['id'],
                name=ele['name'],
                created_at=ele['created_at'],
                type_of_resource=ele['type_of_resource']
            ))
        return pb2.Response(res=resources)
    
    def CreateUser(self, request, context):
        mail = request.mail
        group_id = request.group_id
        group_role = request.group_role
        acct_id = request.acct_id
        acct_role = request.acct_role
        result = main.create_user(email=mail,group_ids={group_id},group_role=group_role,acct_id=acct_id,account_role=acct_role)
        resources=[]
        for ele in result:
            resources.append(pb2.Resource(
                msg=ele['msg'],
                id=ele['id'],
                name=ele['name'],
                created_at=ele['created_at'],
                type_of_resource=ele['type_of_resource']
            ))
        return pb2.Response(res=resources)
    
    def GetApps(self, request, context):
        group_id = request.group_id
        acct_id = request.acct_id
        result = main.get_apps_data_by_group(group_id=group_id,acct_id=acct_id)
        resources=[]
        for ele in result:
            resources.append(pb2.Resource(
                msg=ele['msg'],
                id=ele['id'],
                name=ele['name'],
                created_at=ele['created_at'],
                type_of_resource=ele['type_of_resource']
            ))
        return pb2.Response(res=resources)
    
    def DeleteApp(self, request, context):
        app_id = request.app_id
        acct_id = request.acct_id
        result = main.delete_app(app_id=app_id,acct_id=acct_id)
        resources=[]
        for ele in result:
            resources.append(pb2.Resource(
                msg=ele['msg'],
                id=ele['id'],
                name=ele['name'],
                created_at=ele['created_at'],
                type_of_resource=ele['type_of_resource']
            ))
        return pb2.Response(res=resources)

def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    pb2_grpc.add_ConsumerServicer_to_server(ConsumerServicer(), server)
    server.add_insecure_port('[::]:50051')
    server.start()
    server.wait_for_termination()

def secure_serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    pb2_grpc.add_ConsumerServicer_to_server(
        ConsumerServicer(), server
    )
    with open("server.key", "rb") as fp:
        server_key = fp.read()
    with open("server.pem", "rb") as fp:
        server_cert = fp.read()

    creds = grpc.ssl_server_credentials([(server_key, server_cert)])
    server.add_secure_port("[::]:8448", creds)
    server.start()
    server.wait_for_termination()

if __name__ == '__main__':
    #serve()
    secure_serve()