"""
Secret Token Expiration: 5/5/2024
"""
import os
import logging
import msal
import requests
from graph_api import get_logger, log_it
from typing import List, Dict

class Graph:

    def __init__(
        self,
        client_id: str,
        authority: str,
        app_secret: str,
        logger: logging.Logger = None
    ):

        self._client_id = client_id
        self._authority = authority
        self._app_secret = app_secret
        self._logger = logger or get_logger()
        self._azureconn = self.get_azure_connection()
        self._headers = {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + self.get_azure_token()['access_token'],
            'ConsistencyLevel': 'eventual' #critical for certain query functions, https://docs.microsoft.com/en-us/graph/aad-advanced-queries
        }
        
    @log_it
    def get_azure_connection(self):
        conn = msal.ConfidentialClientApplication(
            self._client_id,  
            authority=self._authority,
            client_credential=self._app_secret
        )
        return conn

    @log_it
    def get_azure_token(self):
        Token = None
        Token = self._azureconn.acquire_token_silent(
            ['https://graph.microsoft.com/.default'],
            account=None
        )

        if not Token:
            self._logger.info("No suitable token exists in cache. Let's get a new one from AAD.")
            Token = self._azureconn.acquire_token_for_client(
                scopes=['https://graph.microsoft.com/.default']
            )
            if 'error' in Token:
                raise Exception(f'Error getting token from Microsoft: {Token}')
        return Token

    @log_it
    def get_azure_data(self, url: str, params: Dict = None, paginate: bool = True) -> List[Dict]:
        resp_list = []
        req = requests.Request(
                                'GET',
                                url,
                                headers=self._headers,
                                params=params 
                            )
        prepared = req.prepare()
        response = requests.Session().send(prepared).json() #did it this way to troubleshoot the prepared query string
        if not response.get('value'):
            print('No Values Returned')
            return
        users = response['value']
        resp_list.extend(users)
        page_countdown = response.get('@odata.count')
        
        if paginate:
            while '@odata.nextLink' in response:
                self._logger.info(page_countdown)
                response = requests.get(response['@odata.nextLink'],
                                        headers=self._headers
                                    ).json()
                users = response['value']
                resp_list.extend(users)
                page_countdown -= params['$top']

        return resp_list