o
    ג[i,                     @   sb   d Z ddlZddlmZmZmZmZ ddlmZ ddl	m
Z
 ddlmZ ddlZG dd dZdS )	a  
MongoDB Service Layer

This module provides all MongoDB database access for the IGF Admin application.
All database operations must go through this service to maintain separation of concerns.

Key principles:
- Single source of truth: MongoDB database
- No hardcoded collection names or database names
- All configuration comes from app_config.yaml
- Read/write operations are explicit and controlled
    N)ListDictAnyOptional)MongoClient)Database)
Collectionc                   @   s  e Zd ZdZd0defddZdedeeef fddZde	fd	d
Z
de	fddZdee fddZdefddZdee fddZdedee fddZdedefddZ		d1dedededeeeef  fddZdedeeef fdd Zdee fd!d"Zd#edee fd$d%Z	&d2d#ededee deeeef  fd'd(Zd#edeeef fd)d*Zded+edee fd,d-Zd.d/ Zd&S )3MongoServicez
    MongoDB service for managing database connections and operations.
    
    This service loads configuration from app_config.yaml and provides
    safe, controlled access to MongoDB collections.
    config/app_config.yamlconfig_pathc                 C   s"   |  || _d| _d| _d| _dS )z
        Initialize MongoDB service with configuration.
        
        Args:
            config_path: Path to YAML configuration file
        N)_load_configconfigclientdb_connection_error)selfr    r   */var/www/html/IGF-ODF-V3/services/mongo.py__init__   s   
zMongoService.__init__returnc                 C   sv   t |d}t|}W d   n1 sw   Y  |di dd}t|}|r3||d d< |S d|d d< |S )z
        Load configuration from YAML file.
        
        Args:
            config_path: Path to configuration file
            
        Returns:
            Configuration dictionary
        rNmongodburi_env	MONGO_URIurizpmongodb://AdminUser:WnE0TjGIafVJutreZL7cTIoWNWU52YyxLVgwCUqIGCGg3YUT@18.184.249.241:27017/?authMechanism=DEFAULT)openyaml	safe_loadgetosgetenv)r   r   fr   r   env_urir   r   r   r   *   s   

zMongoService._load_configc              
   C   s   z;| j d d }| j d d }| j d dd}| j d dd}t|||d| _| jjd | j| | _d	| _W d
S  tyS } zt	|| _W Y d	}~dS d	}~ww )z
        Establish connection to MongoDB.
        
        Returns:
            True if connection successful, False otherwise
        r   r   databaseconnection_timeouti  server_selection_timeout)serverSelectionTimeoutMSconnectTimeoutMSpingNTF)
r   r   r   r   admincommandr   r   	Exceptionstr)r   	mongo_uridatabase_namer$   r%   er   r   r   connectC   s&   
zMongoService.connectc                 C   s:   | j du s
| jdu rdS z
| j jd W dS    Y dS )z
        Check if MongoDB connection is active.
        
        Returns:
            True if connected, False otherwise
        NFr(   T)r   r   r)   r*   r   r   r   r   is_connectedd   s   zMongoService.is_connectedc                 C   s   | j S )z
        Get the last connection error message.
        
        Returns:
            Error message or None if no error
        )r   r1   r   r   r   get_connection_errort   s   z!MongoService.get_connection_errorc                 C   s   | j d d S )zz
        Get the configured database name.
        
        Returns:
            Database name from configuration
        r   r#   )r   r1   r   r   r   get_database_name}   s   zMongoService.get_database_namec                 C   s    | j di }dd | D S )z
        Get list of enabled collections from configuration.
        
        Returns:
            List of collection names that are enabled
        collectionsc                 S   s    g | ]\}}| d dr|qS )enabledT)r   ).0namer   r   r   r   
<listcomp>   s     z1MongoService.list_collections.<locals>.<listcomp>)r   r   items)r   collections_configr   r   r   list_collections   s   zMongoService.list_collectionsr8   c                 C   s   | j du rdS | j | S )z
        Get a MongoDB collection by name.
        
        Args:
            name: Collection name
            
        Returns:
            Collection object or None if not connected
        N)r   )r   r8   r   r   r   get_collection   s   


zMongoService.get_collectioncollection_namec                 C   s:   z|  |}|du rW dS |i W S  ty   Y dS w )z
        Count total documents in a collection.
        
        Args:
            collection_name: Name of the collection
            
        Returns:
            Number of documents, or 0 if error
        Nr   )r=   count_documentsr+   )r   r>   
collectionr   r   r   r?      s   

zMongoService.count_documents2   r   limitskipc              
   C   sz   z|  |}|du rg W S |i ||}t|}|W S  ty< } ztd| d|  g W  Y d}~S d}~ww )a<  
        Retrieve sample documents from a collection.
        
        Args:
            collection_name: Name of the collection
            limit: Maximum number of documents to return
            skip: Number of documents to skip
            
        Returns:
            List of documents as dictionaries
        NzError sampling documents from : )r=   findrC   rB   listr+   print)r   r>   rB   rC   r@   cursor	documentsr/   r   r   r   sample_documents   s   
zMongoService.sample_documentsc              	   C   s   z0|  |}|du ri W S | jd|}|dd|dd|dd|dd|ddd	W S  tyD   | |ddddd	 Y S w )
z
        Get statistics for a collection.
        
        Args:
            collection_name: Name of the collection
            
        Returns:
            Dictionary with collection statistics
        N	collStatscountr   size
avgObjSizestorageSizenindexes)rL   rM   rN   rO   indexes)r=   r   r*   r   r+   r?   )r   r>   r@   statsr   r   r   get_collection_stats   s&   







z!MongoService.get_collection_statsc              
   C   s`   z|   sg W S | j }dd |D W S  ty/ } ztd|  g W  Y d}~S d}~ww )zx
        List all databases on the MongoDB server.
        
        Returns:
            List of database names
        c                 S   s   g | ]}|d vr|qS ))r)   localr   r   )r7   r   r   r   r   r9     s    z3MongoService.list_all_databases.<locals>.<listcomp>zError listing databases: N)r2   r   list_database_namesr+   rG   )r   db_listr/   r   r   r   list_all_databases   s   
zMongoService.list_all_databasesr.   c              
   C   s`   z|   sg W S | j| }| W S  ty/ } ztd| d|  g W  Y d}~S d}~ww )z
        List all collections in a specific database.
        
        Args:
            database_name: Name of the database
            
        Returns:
            List of collection names
        zError listing collections in rD   N)r2   r   list_collection_namesr+   rG   )r   r.   r   r/   r   r   r   list_collections_in_database  s   


z)MongoService.list_collections_in_databaseNc              
   C   s   z%|   sg W S | j| }|| }|r|i |}n|i }t|W S  tyF } ztd| d| d|  g W  Y d}~S d}~ww )a)  
        Export all documents from a collection.
        
        Args:
            database_name: Name of the database
            collection_name: Name of the collection
            limit: Optional limit on number of documents
            
        Returns:
            List of documents
        zError exporting .rD   N)r2   r   rE   rB   rF   r+   rG   )r   r.   r>   rB   r   r@   rH   r/   r   r   r   export_collection_data  s   


z#MongoService.export_collection_datac              
   C   s   z.|   si W S | j| }|d}|dd|dd|dd|dd|dddW S  tyL } ztd	| d
|  i W  Y d}~S d}~ww )z
        Get statistics for a database.
        
        Args:
            database_name: Name of the database
            
        Returns:
            Dictionary with database statistics
        dbStatsr5   r   dataSizerO   rQ   objects)r5   r]   rO   rQ   r^   zError getting stats for rD   N)r2   r   r*   r   r+   rG   )r   r.   r   rR   r/   r   r   r   get_database_stats@  s    







zMongoService.get_database_stats
field_namec              
   C   sZ   z| j | }||W S  ty, } ztd| d| d|  g W  Y d}~S d}~ww )z
        Get distinct values for a field in a collection.
        
        Args:
            collection_name: Name of the collection
            field_name: Name of the field
        
        Returns:
            List of distinct values
        z#Error getting distinct values from rZ   rD   N)r   distinctr+   rG   )r   r>   r`   r@   r/   r   r   r   get_distinct_values]  s   
z MongoService.get_distinct_valuesc                 C   s(   | j dur| j   d| _ d| _dS dS )z+
        Close MongoDB connection.
        N)r   closer   r1   r   r   r   rc   o  s
   


zMongoService.close)r
   )rA   r   )N)__name__
__module____qualname____doc__r,   r   r   r   r   boolr0   r2   r   r3   r4   r   r<   r   r=   intr?   rJ   rS   rW   rY   r[   r_   rb   rc   r   r   r   r   r	      sL    !		

 "
#r	   )rg   r   typingr   r   r   r   pymongor   pymongo.databaser   pymongo.collectionr   r   r	   r   r   r   r   <module>   s    