"""
Secret Token Expiration: 5/5/2024
"""

import logging
from typing import Optional

import msal
import requests

from graph_api import get_logger, log_it


class Graph:

    def __init__(
        self,
        client_id: str,
        authority: str,
        app_secret: str,
        logger: Optional[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: Optional[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
