from rdflib import Graph, Namespace, URIRef, Literal, RDF, RDFS, XSD
from SPARQLWrapper import SPARQLWrapper, POST, BASIC, URLENCODED

class measurement_main():

    def __init__(self, measurement_data_json):
        self.measurement_data_json = measurement_data_json

    def read_ttl_and_store_in_graphdb(self, ttl_file_path, graphdb_endpoint, graphdb_repository, username=None,
                                      password=None):
        """
        Reads RDF data from a Turtle file and stores it in a GraphDB repository.

        :param ttl_file_path: Path to the Turtle file.
        :param graphdb_endpoint: URL of the GraphDB endpoint.
        :param graphdb_repository: Name of the GraphDB repository.
        :param username: (Optional) Username for GraphDB authentication.
        :param password: (Optional) Password for GraphDB authentication.
        """
        # Create a graph
        graph = Graph()

        # Parse the Turtle file
        graph.parse(ttl_file_path, format="turtle")

        # Serialize the graph to a string in N-Triples format
        ntriples_data = graph.serialize(format='nt')

        # If ntriples_data is bytes, decode it to string
        if isinstance(ntriples_data, bytes):
            ntriples_data = ntriples_data.decode('utf-8')

        # Create a SPARQLWrapper instance for the GraphDB endpoint
        sparql = SPARQLWrapper(f"{graphdb_endpoint}/repositories/{graphdb_repository}/statements")
        sparql.setMethod(POST)
        sparql.setRequestMethod(URLENCODED)
        sparql.addParameter('update', f"""
        INSERT DATA {{
            {ntriples_data}
        }}
        """)

        # Set credentials if provided
        if username and password:
            sparql.setHTTPAuth(BASIC)
            sparql.setCredentials(username, password)

        # Send the request to the GraphDB repository
        sparql.query()

    def parse_measurement_data(self):
        # Create a new RDF graph
        g = Graph()
        # Define a custom namespace
        ontology = Namespace("http://sincere.org/s1#")
        resource = Namespace("http://sincere.org/s1/resource/")
        g.bind('sincere', ontology)

        actual_page = self.measurement_data_json["actual_page"]
        count = self.measurement_data_json["count"]
        pagination = self.measurement_data_json["pagination"]
        status = self.measurement_data_json["status"]
        total_pages = self.measurement_data_json["total_pages"]
        count = 1
        for channel in self.measurement_data_json["data"]:
            channel_id = channel["channel_id"]
            data_value = channel["data_value"]
            measurement = channel["measurement"]
            time = channel["time"]
            g.add((resource["channel_" + channel_id], RDF.type, ontology.Channel))
            g.add((resource["measurement_" + channel_id + "_" + str(count)], RDF.type, ontology.Measurement))
            g.add((resource["channel_" + channel_id], ontology.hasMeasurement, resource["measurement_" + channel_id + "_" + str(count)]))
            g.add((resource["measurement_" + channel_id + "_" + str(count)], ontology.value, Literal(data_value, datatype=XSD.float)))
            g.add((resource["measurement_" + channel_id + "_" + str(count)], ontology.measurement, Literal(measurement, datatype=XSD.string)))
            g.add((resource["measurement_" + channel_id + "_" + str(count)], ontology.time, Literal(time, datatype=XSD.string)))
            count += 1

        # Create RDF triples
        # Serialize and save the RDF graph to a TTL file
        file_path = "output_channel.ttl"
        g.serialize(destination=file_path, format="turtle")


        graphdb_endpoint = 'http://localhost:7200'  # Replace with the URL of your GraphDB endpoint
        graphdb_repository = 'weather_measurement'  # Replace with the name of your GraphDB repository
        username = 'admin'  # Replace with your GraphDB username (if required)
        password = 'root'  # Replace with your GraphDB password (if required)

        self.read_ttl_and_store_in_graphdb(file_path, graphdb_endpoint, graphdb_repository, username, password)
        print("Data was mapped in GraphDB")

        return 1