import http.client
import json
from jinja2 import Template
import jmespath
import base64
import os
from xsdata.formats.dataclass.parsers import XmlParser
from xsdata.formats.dataclass.context import XmlContext

# Import generated Data Classes
from data_classes.ei_rest_api import SgrRestapideviceDescriptionType
from data_classes.ei_modbus import SgrModbusDeviceDescriptionType

#instanciate the xsdata parser
interface_file = 'SGr_04_0018_CLEMAP_EIcloudEnergyMonitorV0.2.1.xml'
parser = XmlParser(context=XmlContext())
root = parser.parse(interface_file, SgrRestapideviceDescriptionType)


def add_private_config(string, params):
    jT = Template(string)
    a = jT.render(params['AUTHENTICATION'])
    return a

###################################################################################
# SmartGrid ready External Interface Class for Rest API
###################################################################################
class EI4RestAPI():
    def __init__(self, xmlSGrInterface, private_config):
        self.restapi_resource = root.rest_apiinterface_desc.trsp_srv_rest_uriout_of_box
        restapi_auth_method = root.rest_apiinterface_desc.rest_apiauthentication_method.value

        # Bearer Auth
        if restapi_auth_method == 'BearerSecurityScheme':
            
            bearer = root.rest_apiinterface_desc.rest_apibearer
            endpoint = bearer.rest_apiend_point.split("'")
            print(f"ENDPOINTZ: {endpoint}")
            auth_endpoint = endpoint[2][1:]
            request = endpoint[1]
            json_data = add_private_config(request, private_config)
            restapi_JMES_path = bearer.rest_apijmespath
            self.conn = http.client.HTTPSConnection(self.restapi_resource, timeout=10)
            self.headers = {'Content-type': 'application/json',
                            'Accept': 'application/json'}
            #json_data = json.dumps(json.loads(auth_request))
            self.conn.request('POST', auth_endpoint, json_data, self.headers)
            response = self.conn.getresponse()
            response_dec = json.loads(response.read().decode())
            token = jmespath.search(restapi_JMES_path, response_dec)
            self.headers['Authorization'] = 'Bearer ' + token

        #TODO Basic Auth !!! Need to have an xml file with this structure to do it properly.
        elif restapi_auth_method == 'BasicSecurityScheme':
            auth_location = root.rest_apiinterface_desc.rest_apiauthentication_method.rest_apibasic.rest_apibasic_location

            self.conn = http.client.HTTPSConnection(self.restapi_resource, timeout=10)
            # reads the user and pass, encode it and add it to the header
            u = private_config['AUTHENTICATION']['username']
            p = private_config['AUTHENTICATION']['password']
            s = u + ':' + p
            s_bytes = s.encode('ascii')
            b64_bytes = base64.b64encode(s_bytes)
            b64_string = b64_bytes.decode('ascii')

            self.headers = {'Content-type': 'application/json', 'Authorization': 'Basic ' + b64_string}


        else:
            print('Error')

    def get(self, end_point):
        self.conn = http.client.HTTPSConnection(self.restapi_resource, timeout=10)
        self.conn.request('GET', end_point , '', self.headers)
        print(f"IDEA: {end_point}")
        print(f"IDEA: {self.headers}")
        response = self.conn.getresponse()
        response_dec = json.loads(response.read().decode())
        return response_dec

    def put(self, end_point, value_to_send):
        #TODO to implement
        pass