import numpy as np
import os
# import ipdb
from scipy.special import softmax
import random
import matplotlib.pyplot as plt
import pandas as pd

def read_file(file):
    read_list = []
    with open(file, "r") as filed:
        for line in filed:
            read_list.append(line.strip())
        return read_list
    
def write_file(strings, file):
    with open(file, 'w') as file:
        for s in strings:
            if s[-3:] != "npy":
                continue
            file.write(s + "\n")

def get_output(val_output_path, val_target_path, file):
    output_file = os.path.join(val_output_path, file+".npy")
    target_file = os.path.join(val_target_path, file+"_1_1.npy")
    output = np.load(output_file)   #20 256 256 32
    target = np.load(target_file)   #256 256 32
    output = softmax(output, axis=1)
    output = np.transpose(output, (0,2,3,4,1))
    output = output.reshape((-1, output.shape[-1]))
    target = target.reshape(-1).astype(int)
    index = target != 255
    target = target[index]
    output = output[index]
    return target, output

def compute_quantile(scores, alpha):
    n = scores.shape[0]
    q_level = np.ceil((n+1)*(1-alpha))/n
    if q_level>1 or q_level<0:
        q_level = 1
    q = np.quantile(scores, q_level, interpolation='higher')
    return q

def compute_metrics(TP, FP, FN, TN):
    # Accuracy
    accuracy = (TP + TN) / (TP + TN + FP + FN + 1e-5) * 100
    
    # Precision
    precision = TP / (TP + FP + 1e-5) * 100
    
    # Recall (Sensitivity)
    recall = TP / (TP + FN + 1e-5) * 100
    
    # F1-score (F-measure)
    f1_score = 2 * (precision * recall) / (precision + recall + 1e-9)
    
    # Intersection over Union (IoU)
    IoU = TP / (TP + FP + FN + 1e-5) * 100
    
    return accuracy, precision, recall, f1_score, IoU

def read_previous_occupanied_results(results_path, store_result_file):
    data = np.load(os.path.join(results_path, store_result_file), allow_pickle=True)
    return data[0], data[1], data[2], data[3]

def check_npy_file(file):
    return file[-3:] == "npy"

def handle_thresholds(thresholds, considered_class):
    for i in range(len(thresholds)):
        if i not in considered_class:
            thresholds[i] = -1.0
    return thresholds

def create_folder_if_not_exists(folder_path):
    """
    Check if a folder exists at the specified path.
    If it doesn't exist, create it.
    
    Parameters:
    - folder_path (str): Path of the folder to check/create.
    """
    if not os.path.exists(folder_path):
        os.makedirs(folder_path)
        print(f"Folder '{folder_path}' created.")
    else:
        print(f"Folder '{folder_path}' already exists.")

def read_previous_occupanied_results(store_result_file):
    data = np.load(store_result_file, allow_pickle=True)
    return data[0], data[1], data[2], data[3]

class_name_dict = {0: "empty", 1: "car" , 2: "bicycle" , 3: "motorcycle" , 4:  "truck",  
5: "other-vehicle", 6: "person" , 7:"bicyclist" , 8: "motorcyclist" , 9: "road",
10: "parking" , 11: "sidewalk" , 12: "other-ground" , 13: "building" , 14: "fence",
15:  "vegetation" , 16:  "trunk" , 17:  "terrain" , 18:  "pole" , 19: "traffic-sign", 20: "All Occupied"
}

