from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider
import ssl
import os
from .base_db import BaseDBHandler

class CassandraHandler(BaseDBHandler):
    def __init__(self, logger):
        super().__init__(logger)
        # Get certificate path from environment variable
        self.cert_path = os.getenv("EURECA_CA")

    def connect(self, service, user, password, database=None):
        contact_points = [host.strip() for host in service.split(',')]
        # Set up authentication if provided
        auth_provider = None
        if user and password:
            auth_provider = PlainTextAuthProvider(username=user, password=password)

        try:
            # Set up SSL context
            ssl_context = ssl.create_default_context()
            ssl_context.check_hostname = False
            ssl_context.verify_mode = ssl.CERT_NONE
            ssl_context.load_verify_locations(self.cert_path)

            self.cluster = Cluster(
                contact_points=contact_points,
                port=9042,
                auth_provider=auth_provider,
                ssl_context=ssl_context,
                ssl_options={'check_hostname': False}
            )
            self.session = self.cluster.connect(database) if database else self.cluster.connect()
            self.session.execute("SELECT release_version FROM system.local")
            return self.make_connection_response("Successfully connected to Cassandra ")
        except Exception as e:
            return self.make_error_response(500,f"Failed to connect to Cassandra: {e}")

    def execute_query(self, query, database=None):
        try:
            if database:
                if hasattr(self.session, 'keyspace') and self.session.keyspace != database:
                    self.session.set_keyspace(database)
                elif not hasattr(self.session, 'keyspace') or self.session.keyspace is None:
                    self.session.set_keyspace(database)

            # Execute the CQL query
            result = self.session.execute(query)
            query_lower = query.strip().lower()

            if query_lower.startswith(("select", "describe", "show")):
                rows = list(result)
                if rows:
                    columns_names = list(result.column_names) if hasattr(result, 'column_names') and result.column_names else []
                    if not columns_names and rows and hasattr(rows[0], '_fields'):
                        columns_names = list(rows[0]._fields)

                    results = []
                    for row in rows:
                        if hasattr(row, '_asdict'):
                            results.append(list(row._asdict().values()))
                        elif hasattr(row, '__iter__') and not isinstance(row, (str, bytes)):
                            results.append(list(row))
                        else:
                            results.append([row])

                    return self.make_success_response(
                        columns_names=columns_names,
                        results=results
                    )
                else:
                    return self.make_success_response(
                        msg="Query executed successfully, no results returned",
                        columns_names=[],
                        results=[]
                    )
            elif query_lower.startswith(("insert", "update", "delete", "create", "drop", "alter", "truncate", "use")):
                # Data modification or DDL query
                return self.make_success_response(
                    msg="Query executed successfully",
                    columns_names=[],
                    results=[]
                )
            else:
                return self.make_success_response(
                    msg="Query executed successfully",
                    columns_names=[],
                    results=[]
                )

        except Exception as e:
            return self.make_error_response(500, f"Internal Server Error, Please check the query and try again: {e}")
