# global imports (dont't worry, red is normal)
import network_constants as netconst
from database.MongoRepositoryBase import MongoRepositoryBase
from db.entities.layer_adapter import LayerAdapter
from db.entities.use_case import UseCase

import pymongo
import json
from typing import List, Dict

class Repository(MongoRepositoryBase):
    '''This is a repository for MongoDb.'''

    def __init__(self):
        super().__init__(netconst.BUSINESS_LOGIC_DB_HOSTNAME,
                         netconst.BUSINESS_LOGIC_DB_PORT,
                         'business-logic-db')

        self._adapter_collection = 'layer_adapters'
        self._use_case_collection = 'use_cases'
    
    def all(self) -> List[Dict]:
        result = super().get_entries(self._adapter_collection, projection={'_id': False})

        return [LayerAdapter.from_serializable_dict(row) for row in list(result)]
    
    def all_for_use_case(self, use_case: str) -> List[LayerAdapter]:
        result = super().get_entries(self._adapter_collection, projection={'_id': False}, selection={"use_case": use_case})

        return [LayerAdapter.from_serializable_dict(row) for row in list(result)]

    def all_for_use_case_and_table(self, use_case: str, table: str) -> List[LayerAdapter]:
        result = super().get_entries(self._adapter_collection, projection={'_id': False}, selection={"use_case": use_case, "table": table})

        return [LayerAdapter.from_serializable_dict(row) for row in list(result)]

    def one(self, name : str, use_case: str, table: str) -> LayerAdapter:
        result = list(super().get_entries(self._adapter_collection, selection={"name": name, "use_case": use_case, "table": table}))

        if len(result) == 1:
            return LayerAdapter.from_serializable_dict(result[0])
        
        return None

    def delete_all(self):
        collection = self._database[self._adapter_collection]
        collection.delete_many({})

    def add(self, adapter : LayerAdapter):
        super().insert_entry(self._adapter_collection, adapter.to_serializable_dict())

    def update_use_case(self, adapter : LayerAdapter, use_case: str):
        collection = self._database[self._adapter_collection]
        collection.update_one({"name":adapter.name, "use_case": use_case, "table": adapter.table}, {"$set": adapter.to_serializable_dict()})
    
    def update(self, adapter : LayerAdapter):
        collection = self._database[self._adapter_collection]
        collection.update_one({"name":adapter.name, "use_case": adapter.use_case, "table": adapter.table}, {"$set": adapter.to_serializable_dict()})
    
    def delete(self, adapter : LayerAdapter):
        collection = self._database[self._adapter_collection]
        collection.delete_many({"name": adapter.name, "use_case": adapter.use_case, "table": adapter.table})