from sqlalchemy.orm import Session

from ..model.custom_action_adapter import CustomActionAdapter
from ..model.runtime import Runtime
from ..model.trackedchange import TrackedChange


def get_custom_action_adapter_record(
    session: Session,
    is_sql_server: bool,
    node_id: str,
    adapter_name: str,
    assembly_name: str,
    type_name: str,
    connection_string: str,
    load_order: int,
    enabled: bool,
) -> CustomActionAdapter | None:
    try:
        # Lookup custom action adapter record by adapter name, creating a new record if one does not exist
        adapter_record = (
            session.query(CustomActionAdapter).filter(CustomActionAdapter.AdapterName == adapter_name).one_or_none()
        )

        if adapter_record:
            # If the record exists, check if it matches the provided details
            if (
                str(adapter_record.NodeID) == node_id
                and str(adapter_record.AssemblyName) == assembly_name
                and str(adapter_record.TypeName) == type_name
                and str(adapter_record.ConnectionString) == connection_string
                and int(adapter_record.LoadOrder) == load_order
                and bool(adapter_record.Enabled) == enabled
            ):
                return adapter_record
        else:
            adapter_record = CustomActionAdapter()

        # Update record fields
        adapter_record.NodeID = node_id
        adapter_record.AdapterName = adapter_name
        adapter_record.AssemblyName = assembly_name
        adapter_record.TypeName = type_name
        adapter_record.ConnectionString = connection_string
        adapter_record.LoadOrder = load_order
        adapter_record.Enabled = enabled

        # Save record updates
        session.add(adapter_record)
        session.commit()

        # Re-query to get any database assigned information
        adapter_record = (
            session.query(CustomActionAdapter).filter(CustomActionAdapter.AdapterName == adapter_name).one()
        )

        runtime_record = (
            session.query(Runtime)
            .filter(Runtime.SourceID == adapter_record.ID, Runtime.SourceTable == "CustomActionAdapter")
            .one_or_none()
        )

        # Manually insert the adapter record details into the Runtime table, if it doesn't exist
        if not runtime_record:
            runtime_record = Runtime()
            runtime_record.SourceID = adapter_record.ID
            runtime_record.SourceTable = "CustomActionAdapter"

            session.add(runtime_record)
            session.commit()

        if is_sql_server:
            # Manually insert the adapter record details into the TrackedChange table (in lieu of triggers)
            trackedchange_record = TrackedChange()
            trackedchange_record.TableName = "CustomActionAdapter"
            trackedchange_record.PrimaryKeyColumn = "ID"
            trackedchange_record.PrimaryKeyValue = str(adapter_record.ID)

            session.add(trackedchange_record)
            session.commit()

        return adapter_record
    except Exception as e:
        session.rollback()
        print(f'Error occurred while reading or creating CustomActionAdapter record for "{adapter_name}": {e}')
        return None
