import numpy as np
import pandas as pd
import networkx as nx
from pgmpy.readwrite import BIFReader
rename_mapping_win95pts = {
	'AppData': 'Application Data Incorrect or corrupt',
	'DskLocal': 'Local Disk Space Less than 2 Mb',
	'PrtSpool': 'Print Spooling Disabled',
	'PrtData': 'No Print Data',
	'PrtCbl': 'Local Printer Cable Loose',
	'PrtOn': 'Printer Not On or Not Online',
	'PrtThread': 'Port thread/Prt Proc Corrupt/Buggy',
	'GDIOUT': 'GDI Output Not OK',
	'EMFOK': 'EMF Not OK',
	'PrtDriver': 'Incorrect Driver',
	'GDIIN': 'GDI Input Not OK',
	'Problem1': 'No Output',
	'PrtPaper': 'Printer Paper Supply: No Paper',
	'DrvSet': 'Incorrect Driver Configuration',
	'NetPrint': 'Printing over Network Printer Not Local Printer',
	'PrtDataOut': 'Not Print Data Out',
	'PrtPath': 'Incorrect Net Printer Pathname',
	'PC2PRT': 'No PC to PRT Transport',
	'NetOK': 'NET Not OK',
	'DrvOK': 'Driver File Status: Corrupt',
	'PrtSel': 'Incorrect Printer Selected',
	'PrtMem': 'Printer Memory Less than 2Mb',
	'LclOK': 'LOCAL Not OK',
	'PrtPort': 'Incorrect Local Port',
	'DeskPrntSpd': 'Desk Speed Too Slow',
	'CblPrtHrdwrOK': 'Cable/Port Hardware Not Operational',
	'DSApplctn': 'Windows Print Environment Not DOS',
	'DS_NTOK': 'DOS-NET Not OK',
	'DS_LCLOK': 'DOS-LOCAL Not OK',
	'PrtMpTPth': 'Incorrect Port Mapping to Path',
	'PgOrnttnOK': 'Incorrect Page Orientation',
	'PrntngArOK': 'Incorrect Printer Printing Area',
	'ScrnFntNtPrntrFnt': 'Screen Not Matches Printer',
	'CmpltPgPrntd': 'Non PS Not Complete',
	'Problem4': 'Graphics Distorted or Incomplete',
	'GrphcsRltdDrvrSttngs': 'Incorrect Driver Config- Graphics',
	'Problem5': 'Fonts Missing or Distorted',
	'TrTypFnts': 'Not True Type Fonts',
	'FntInstlltn': 'Font Faulty Installation',
	'PrntrAccptsTrtyp': 'Printer Not Accepts Truetype',
	'TTOK': 'TT Not OK',
	'GrbldOtpt': 'Non PS Garbled',
	'NtwrkCnfg': 'Incorrect Network Configuration',
	'NnTTOK': 'Non TT Not OK',
	'AppDtGnTm': 'App Data Generation Too Long',
	'PrntPrcssTm': 'Print Processing Too Long',
	'HrglssDrtnAftrPrnt': 'Hourglass Duration Too Long',
	'LclGrbld': 'Local Garbled Not OK',
	'NtGrbld': 'Net Garbled Not OK',
	'NnPSGrphc': 'No Non PS Graphic',
	'REPEAT': 'Not Repeatable Problem',
	'PrtTimeOut': 'Printer Timeouts Too Short',
	'PrtPScript': 'No Postscript Printer',
	'AvlblVrtlMmry': 'Printer Virtual Mem Inadequate',
	'PSERRMEM': 'PS Error Memory: Low Memory',
	'TstpsTxt': 'testps.txt Output: <1 Mb Available VM',
	'GrbldPS': 'PS Garbled',
	'IncmpltPS': 'PS Not Complete',
	'EPSGrphc': 'EPS Graphic Not *.TIF,*.WMF,*.BMP',
	'PSGRAPHIC': 'Not PS Graphic',
	'FllCrrptdBffr': 'Print Buffer Full or Corrupt',
	'AppOK': 'Application Incorrect/Corrupt',
	'DataFile': 'Document Incorrect/Corrupt',
	'PrtFile': 'Not Print to File',
	'PrtIcon': 'Printer Icon Grayed Out',
	'Problem6': 'Garbled Output',
	'Problem3': 'Incomplete Page',
	'NtSpd': 'Net Speed Slow',
	'Problem2': 'Too Slow',
	'PrtQueue': 'Printer Queue Long',
	'PrtStatPaper': 'Printer Status - Paper (Jam/Out/Bin Full)',
	'PrtStatToner': 'Printer Status - Toner Low',
	'PrtStatMem': 'Printer Status - Out of Memory',
	'PrtStatOff': 'Printer Status - Offline',
	'TnrSpply': 'Toner Supply Low',
	'PTROFFLINE': 'Printer Driver Set Offline'
}

# Issue-code mapping (1 = problem, 0 = okay)
value_mappings_win95pts = {
	'Application Data Incorrect or corrupt': {'Incorrect_or_corrupt':1, 'Correct':0},
	'Local Disk Space Less than 2 Mb': {'Less_than_2_Mb':1, 'Greater_than_2_Mb':0},
	'Print Spooling Disabled': {'Disabled':1, 'Enabled':0},
	'No Print Data': {'No':1, 'Yes':0},
	'Local Printer Cable Loose': {'Loose':1, 'Connected':0},
	'Printer Not On or Not Online': {'No':1, 'Yes':0},
	'Port thread/Prt Proc Corrupt/Buggy': {'Corrupt_Buggy':1, 'OK':0},
	'GDI Output Not OK': {'No':1, 'Yes':0},
	'EMF Not OK': {'No':1, 'Yes':0},
	'Incorrect Driver': {'No':1, 'Yes':0},
	'GDI Input Not OK': {'No':1, 'Yes':0},
	'No Output': {'No_Output':1, 'Normal_Output':0},
	'Printer Paper Supply: No Paper': {'No_Paper':1, 'Has_Paper':0},
	'Incorrect Driver Configuration': {'Incorrect':1, 'Correct':0},
	'Printing over Network Printer Not Local Printer': {'Yes__Network_printer_':1, 'No__Local_printer_':0},
	'Not Print Data Out': {'No':1, 'Yes':0},
	'Incorrect Net Printer Pathname': {'Incorrect':1, 'Correct':0},
	'No PC to PRT Transport': {'No':1, 'Yes':0},
	'NET Not OK': {'No':1, 'Yes':0},
	'Driver File Status: Corrupt': {'Corrupt':1, 'Reinstalled':0},
	'Incorrect Printer Selected': {'No':1, 'Yes':0},
	'Printer Memory Less than 2Mb': {'Less_than_2Mb':1, 'Greater_than_2_Mb':0},
	'LOCAL Not OK': {'No':1, 'Yes':0},
	'Incorrect Local Port': {'No':1, 'Yes':0},
	'Desk Speed Too Slow': {'Too_Slow':1, 'OK':0},
	'Cable/Port Hardware Not Operational': {'Not_Operational':1, 'Operational':0},
	'Windows Print Environment Not DOS': {'Windows':1, 'DOS':0},
	'DOS-NET Not OK': {'No':1, 'Yes':0},
	'DOS-LOCAL Not OK': {'No':1, 'Yes':0},
	'Incorrect Port Mapping to Path': {'Incorrect':1, 'Correct':0},
	'Incorrect Page Orientation': {'Incorrect':1, 'Correct':0},
	'Incorrect Printer Printing Area': {'Incorrect':1, 'Correct':0},
	'Screen Not Matches Printer': {'No':1, 'Yes':0},
	'Non PS Not Complete': {'No':1, 'Yes':0},
	'Graphics Distorted or Incomplete': {'Yes':1, 'No':0},
	'Incorrect Driver Config- Graphics': {'Incorrect':1, 'Correct':0},
	'Fonts Missing or Distorted': {'Yes':1, 'No':0},
	'Not True Type Fonts': {'No':1, 'Yes':0},
	'Font Faulty Installation': {'Faulty':1, 'Verified':0},
	'Printer Not Accepts Truetype': {'No':1, 'Yes':0},
	'TT Not OK': {'No':1, 'Yes':0},
	'Non PS Garbled': {'Yes':1, 'No':0},
	'Incorrect Network Configuration': {'Incorrect':1, 'Correct':0},
	'Non TT Not OK': {'No':1, 'Yes':0},
	'App Data Generation Too Long': {'Too_Long':1, 'Fast_Enough':0},
	'Print Processing Too Long': {'Too_Long':1, 'Fast_Enough':0},
	'Hourglass Duration Too Long': {'Too_Long':1, 'Fast_Enough':0},
	'Local Garbled Not OK': {'No':1, 'Yes':0},
	'Net Garbled Not OK': {'No':1, 'Yes':0},
	'No Non PS Graphic': {'No':1, 'Yes':0},
	'Not Repeatable Problem': {'No__Different_Each_Time_':1, 'Yes__Always_the_Same_':0},
	'Printer Timeouts Too Short': {'Too_Short':1, 'Long_Enough':0},
	'No Postscript Printer': {'No':1, 'Yes':0},
	'Printer Virtual Mem Inadequate': {'Inadequate____1_Mb_':1, 'Adequate____1Mb_':0},
	'PS Error Memory: Low Memory': {'Low_Memory':1, 'No_Error':0},
	'testps.txt Output: <1 Mb Available VM': {'x_1_Mb_Available_VM2':1, 'x_1_Mb_Available_VM':0},
	'PS Garbled': {'Yes':1, 'No':0},
	'PS Not Complete': {'No':1, 'Yes':0},
	'EPS Graphic Not *.TIF,*.WMF,*.BMP': {'Yes____EPS_':1, 'No____TIF___WMF___BMP_':0},
	'Not PS Graphic': {'No':1, 'Yes':0},
	'Print Buffer Full or Corrupt': {'Full_or_Corrupt':1, 'Intact__not_Corrupt_':0},
	'Application Incorrect/Corrupt': {'Incorrect_Corrupt':1, 'Correct':0},
	'Document Incorrect/Corrupt': {'Incorrect_Corrupt':1, 'Correct':0},
	'Not Print to File': {'No':1, 'Yes':0},
	'Printer Icon Grayed Out': {'Grayed_Out':1, 'Normal':0},
	'Garbled Output': {'Yes':1, 'No':0},
	'Incomplete Page': {'Yes':1, 'No':0},
	'Net Speed Slow': {'Slow':1, 'OK':0},
	'Too Slow': {'Too_Long':1, 'OK':0},
	'Printer Queue Long': {'Long':1, 'Short':0},
	'Printer Status - Paper (Jam/Out/Bin Full)': {'Jam__Out__Bin_Full':1, 'No_Error':0},
	'Printer Status - Toner Low': {'Low__None':1, 'No_Error':0},
	'Printer Status - Out of Memory': {'Out_of_Memory':1, 'No_Error':0},
	'Printer Status - Offline': {'OFFLINE__OFF':1, 'No_Error':0},
	'Toner Supply Low': {'Low':1, 'Adequate':0},
	'Printer Driver Set Offline': {'Offline':1, 'Online':0}
}

# Compact variable descriptions (adverse first / ok second)
variable_description_win95pts = {
	label: f"Two-level: {list(mapping.keys())[0]} / {list(mapping.keys())[1]}"
	for label, mapping in value_mappings_win95pts.items()
}

dataset_description_win95pts = (
	"The dataset is generated from the Microsoft Windows 95 Print Troubleshooter influence diagram. Each record "
	"encodes the presence (1) or absence (0) of potential faults and status "
	"signals spanning application integrity, printer hardware, driver setup, "
	"data-path, network, memory, and user-visible symptoms."
)

def fetch_win95pts():
    df = pd.read_csv(f'/net/dali/home/mscbio/rul98/CausalLLM/data/win95pts_20000.csv')

    # Normalize all missing values (including string "<NA>")
    df = df.replace(["<NA>", "nan", pd.NA], "None")

    # Rename columns
    df = df.rename(columns=rename_mapping_win95pts)

    # Apply value mappings
    for col, mapping in value_mappings_win95pts.items():
        if col in df.columns:
            df[col] = df[col].astype("str").map(mapping).astype("Int64")  

    reader = BIFReader(f'/net/dali/home/mscbio/rul98/CausalLLM/data/win95pts.bif')
    G_model = reader.get_model()

    # Create a directed graph from the edges
    GroundTruth = nx.DiGraph()
    GroundTruth.add_nodes_from(G_model.nodes())
    GroundTruth.add_edges_from(G_model.edges())
    GroundTruth = nx.relabel_nodes(GroundTruth, rename_mapping_win95pts)
    pos_data = nx.spring_layout(GroundTruth)
    # print(set(GroundTruth.nodes()) - set(df.columns), set(df.columns) - set(GroundTruth.nodes()))
    return df, GroundTruth, pos_data