"""
Pearson Service Insight's Divvy API Module
This module contains a class with methods to interact with the Divvy API.
"""
import base64
import json
import logging
import os
import sys

from typing import List

import requests

DIVVY_V2_API_URL = os.environ.get('DIVVY_V2_API_URL', 'https://pearsonedu.customer.divvycloud.com/v2')


class Divvy:

    def __init__(self, api_key: str, logger: logging.Logger = None):

        self._logger = logger if logger else self._get_logger()
        self._headers = {
            'Accept': 'application/json',
            'Api-Key': api_key,
            'Content-Type': 'application/json'
        }

    def get_compliance_scores(self, data: dict) -> dict:
        """Return all results from the divy endpoint as json        

        Parameters
        ----------
        data : dict
            ex:
                data = {"pack_id":24,"organization_service_ids":[9320],"pack_source":"custom","days":3,"badges":[],"badge_filter_operator":"OR","start_date":"2021-09-30","end_date":"2021-10-06"}

            organization_service_ids? 9320 = Governator, these need to be mapped to our accounts as they are Divvy ids.  Will be addressed in future ticket.
        
        Returns
        -------
            ...large json
            {
                "severity_data": {
                    "10/07/2021": {
                        "aws_count": 1,
                        "gcp_count": 0,
                        "azure_count": 0,
                        "alibaba_count": 0,
                        "kubernetes_count": 0,
                        "oracle_count": 0,
                        "total_findings": 166,
                        "resources_in_scope": 1289,
                        "minor": 5,
                        "moderate": 3,
                        "major": 105,
                        "severe": 50,
                        "critical": 3,
                        "total_count": 1
                    }
                },
                "insights_by_severity": {
                    "minor": 2,
                    "moderate": 6,
                    "major": 13,
                    "severe": 10,
                    "critical": 6
                },
                "exemption_counts": {
                    "Minor": 0,
                    "Moderate": 0,
                    "Major": 0,
                    "Severe": 0,
                    "Critical": 0
                },
                "pack_data": {
                    "09/30/2021": {
                        "backoffice_count": 31,
                        "custom_count": 7,
                        "exemption_count": 0
                    }
                },
                "snapshot": {
                    "compliance_score": 0.8712179984484096,
                    "severity_counts": {
                        "minor": {
                            "severity_rank": 1,
                            "findings": 5,
                            "insights": 2,
                            "exemptions": 0,
                            "diff_percent": 0
                        },
                        "moderate": {
                            "severity_rank": 2,
                            "findings": 3,
                            "insights": 6,
                            "exemptions": 0,
                            "diff_percent": 0
                        },
                        "major": {
                            "severity_rank": 3,
                            "findings": 105,
                            "insights": 13,
                            "exemptions": 0,
                            "diff_percent": -0.018691588785046728
                        },
                        "severe": {
                            "severity_rank": 4,
                            "findings": 50,
                            "insights": 10,
                            "exemptions": 0,
                            "diff_percent": 0
                        },
                        "critical": {
                            "severity_rank": 5,
                            "findings": 3,
                            "insights": 6,
                            "exemptions": 0,
                            "diff_percent": 0
                        }
                    },
                    "total_findings": 166,
                    "total_resources": 1289,
                    "total_exemptions": 0,
                    "date": "10/07/2021"
                },
                "trends_over_time": {
                    "compliance_scores": [
                        {
                            "date": "09/30/2021",
                            "total": 0.8608964451313755,
                            "minor": 0.7727272727272727,
                            "moderate": 0.9754098360655737,
                            "major": 0.746268656716418,
                            "severe": 0.8538011695906432,
                            "critical": 0.9911504424778761
                        }],
                    "findings_by_severity": {
                        "minor": [
                            {
                                "date": "09/30/2021",
                                "value": 5
                            }],
                        "moderate": [
                            {
                                "date": "09/30/2021",
                                "value": 3
                            }],
                        "major": [
                            {
                                "date": "09/30/2021",
                                "value": 119
                            }],
                        "severe": [
                            {
                                "date": "09/30/2021",
                                "value": 50
                            }],
                        "critical": [
                            {
                                "date": "09/30/2021",
                                "value": 3
                            }]
                    },
                    "insight_counts": {
                        "backoffice": [
                            {
                                "date": "09/30/2021",
                                "value": 31
                            }],
                        "custom": [
                            {
                                "date": "09/30/2021",
                                "value": 7
                            }],
                        "exemptions": [
                            {
                                "date": "09/30/2021",
                                "value": 0
                            }]
                    },
                    "cloud_counts": {
                        "AWS": [
                            {
                                "date": "09/30/2021",
                                "value": 1
                            }],
                        "GCE": [
                            {
                                "date": "09/30/2021",
                                "value": 0
                            }],
                        "AZURE_ARM": [
                            {
                                "date": "09/30/2021",
                                "value": 0
                            }],
                        "ALICLOUD": [
                            {
                                "date": "09/30/2021",
                                "value": 0
                            }],
                        "K8S": [
                            {
                                "date": "09/30/2021",
                                "value": 0
                            }],
                        "OCI": [
                            {
                                "date": "09/30/2021",
                                "value": 0
                            }]
                    }
                }
            }
        """
        url = DIVVY_V2_API_URL + '/compliance/system/report'
        response = requests.post(url,
                                headers=self._headers,
                                data=json.dumps(data))
        self._logger.debug(response.request.headers)
        self._logger.info(f'{response.request.method} {response.request.url}')
        response.raise_for_status()
        return response.json()

    def get_cloud_listing(self, data: dict):
        """Returns 
            data : dict
                ex:
                    data = {"limit":25,"offset":0,"empty_badges":False,"order_by":"name","badges":[],"badge_filter_operator":"OR","filters":[]}
        Returns:
            {   'clouds': [   {   'account_id': 'cogmed-216121',
                      'badge_count': 1,
                      'cloud_organization_id': '443334724975',
                      'cloud_type_id': 'GCE',
                      'creation_time': '2020-12-07 20:58:33',
                      'disabled_resource_types': [   'sharedfilesystem',
                                                     'serviceencryptionkey',
                                                     'mapreducecluster',
                                                     'dbinstance',
                                                     'database',
                                                     'dbsnapshot',
                                                     'notificationtopic',
                                                     'notificationsubscription',
                                                     'servicecost',
                                                     'instance',
                                                     'networkpeer',
                                                     'privatenetwork',
                                                     'privatesubnet',
                                                     'publicip',
                                                     'loadbalancer',
                                                     'networkinterface',
                                                     'resourceaccesslist',
                                                     'servicecertificate',
                                                     'snapshot',
                                                     'autoscalinggroup',
                                                     'privateimage',
                                                     'servicelimit',
                                                     'serviceuser',
                                                     'servicegroup',
                                                     'servicerole',
                                                     'servicepolicy',
                                                     'serviceaccesskey',
                                                     'servicemanagedpolicy',
                                                     'bigdatainstance',
                                                     'distributedtablecluster',
                                                     'serverlessfunction',
                                                     'spanner',
                                                     'spannerdatabase',
                                                     'dnszone',
                                                     'containercluster',
                                                     'mlinstance',
                                                     'mcinstance',
                                                     'identityprovider'],
                      'event_driven_harvest_role': 'idle',
                      'group_resource_id': 'divvyorganizationservice:7605',
                      'id': 7605,
                      'last_refreshed': '2021-10-13 12:08:45',
                      'name': ' cogmed-216121',
                      'resource_count': 47,
                      'resource_id': 'divvyorganizationservice:7605',
                      'role_arn': 'divvycloud-gcp-integration@masterserviceaccount.iam.gserviceaccount.com',
                      'status': 'DEFAULT',
                      'strategy_id': 3}]
            }
        """
        url = DIVVY_V2_API_URL + '/public/clouds/list'
        response = requests.post(url,
                                headers=self._headers,
                                data=json.dumps(data))
        self._logger.debug(response.request.headers)
        self._logger.info(f'{response.request.method} {response.request.url}')
        response.raise_for_status()
        return response.json()
        
    def _get_logger(self, log_level: str = 'info') -> logging.Logger:
        """Return a logger with the given logging level set"""
        handler = logging.StreamHandler(sys.stdout)
        log = logging.getLogger('prometheus_exporter')
        log_level = log_level.lower()
        if log_level == 'debug':
            log.setLevel(logging.DEBUG)
            handler.setLevel(logging.DEBUG)
        elif log_level == 'warning':
            log.setLevel(logging.WARNING)
            handler.setLevel(logging.WARNING)
        elif log_level == 'error':
            log.setLevel(logging.ERROR)
            handler.setLevel(logging.ERROR)
        elif log_level == 'critical':
            log.setLevel(logging.CRITICAL)
            handler.setLevel(logging.CRITICAL)
        else:
            log.setLevel(logging.INFO)
            handler.setLevel(logging.INFO)

        formatter = logging.Formatter(
            '%(asctime)s [%(levelname)s] %(filename)s:%(lineno)d - %(message)s')
        handler.setFormatter(formatter)
        log.addHandler(handler)
        log.propagate = False
        return log

    def __repr__(self) -> str:
        """Return a string representation of the object"""
        return f"Divvy()"


def main():
    api = Divvy('')
    results = api.get_compliance_scores(data={"pack_id":24,"organization_service_ids":[9320],"pack_source":"custom","days":3,"badges":[],"badge_filter_operator":"OR","start_date":"2021-09-30","end_date":"2021-10-06"})
    print(json.dumps(results, indent=4))


if __name__ == '__main__':
    main()
