#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Apr  1 16:43:04 2025

@author: wqg
"""
import os
import pickle
import numpy as np
from scipy.spatial.distance import cdist


def int8_to_ft16(arr_uint8, amin, amax):
    arr_ft16 = (arr_uint8 / 255 * (amax-amin) + amin).astype(np.float16)
    
    return arr_ft16
    
def ft16_to_uint8(arr_ft16):
    # pickpath = r"\\192.168.1.28\share\测试_202406\contrast\std_features_ft32vsft16\6902265587712_ft16.pickle"
    
    # with open(pickpath, 'rb') as f:  
    #     edict = pickle.load(f)
        
    # arr_ft16 = edict['feats']
    
    amin = np.min(arr_ft16)
    amax = np.max(arr_ft16)
    arr_ft255 = (arr_ft16 - amin) * 255 / (amax-amin)
    arr_uint8 = arr_ft255.astype(np.uint8)

    arr_ft16_ = int8_to_ft16(arr_uint8, amin, amax)

    arrDistNorm = np.linalg.norm(arr_ft16_ - arr_ft16) / arr_ft16_.size

    return arr_uint8, arr_ft16_


def data_precision_compare(stdfeat, evtfeat, evtMessage, similPath='', save=True):
    evt, stdbcd, label = evtMessage
    rltdata, rltdata_ft16, rltdata_ft16_ = [], [], []

    matrix = 1 - cdist(stdfeat, evtfeat, 'cosine')
    simi_mean = np.mean(matrix)
    simi_max  = np.max(matrix)
    stdfeatm = np.mean(stdfeat, axis=0, keepdims=True)
    evtfeatm = np.mean(evtfeat, axis=0, keepdims=True)
    simi_mfeat = 1- np.maximum(0.0, cdist(stdfeatm, evtfeatm, 'cosine'))
    rltdata = [label, stdbcd, evt, simi_mean, simi_max, simi_mfeat[0,0]]
    
    
    ##================================================================= float16
    stdfeat_ft16 = stdfeat.astype(np.float16)
    evtfeat_ft16 = evtfeat.astype(np.float16)
    stdfeat_ft16 /= np.linalg.norm(stdfeat_ft16, axis=1)[:, None]
    evtfeat_ft16 /= np.linalg.norm(evtfeat_ft16, axis=1)[:, None]
    
    
    matrix_ft16 = 1 - cdist(stdfeat_ft16, evtfeat_ft16, 'cosine')
    simi_mean_ft16 = np.mean(matrix_ft16)
    simi_max_ft16  = np.max(matrix_ft16)
    stdfeatm_ft16 = np.mean(stdfeat_ft16, axis=0, keepdims=True)
    evtfeatm_ft16 = np.mean(evtfeat_ft16, axis=0, keepdims=True)
    simi_mfeat_ft16 = 1- np.maximum(0.0, cdist(stdfeatm_ft16, evtfeatm_ft16, 'cosine'))
    rltdata_ft16 = [label, stdbcd, evt, simi_mean_ft16, simi_max_ft16, simi_mfeat_ft16[0,0]]
    
    '''****************** uint8 is ok!!!!!! ******************'''
    ##=================================================================== uint8
    # stdfeat_uint8, stdfeat_ft16_ = ft16_to_uint8(stdfeat_ft16)
    # evtfeat_uint8, evtfeat_ft16_ = ft16_to_uint8(evtfeat_ft16)
    
    stdfeat_uint8 = (stdfeat_ft16*128).astype(np.int8)
    evtfeat_uint8 = (evtfeat_ft16*128).astype(np.int8)
    stdfeat_ft16_ = stdfeat_uint8.astype(np.float16)/128
    evtfeat_ft16_ = evtfeat_uint8.astype(np.float16)/128

    absdiff = np.linalg.norm(stdfeat_ft16_ - stdfeat) / stdfeat.size
    
    matrix_ft16_ = 1 - cdist(stdfeat_ft16_, evtfeat_ft16_, 'cosine')
    simi_mean_ft16_ = np.mean(matrix_ft16_)
    simi_max_ft16_  = np.max(matrix_ft16_)
    stdfeatm_ft16_ = np.mean(stdfeat_ft16_, axis=0, keepdims=True)
    evtfeatm_ft16_ = np.mean(evtfeat_ft16_, axis=0, keepdims=True)
    simi_mfeat_ft16_ = 1- np.maximum(0.0, cdist(stdfeatm_ft16_, evtfeatm_ft16_, 'cosine'))
    rltdata_ft16_ = [label, stdbcd, evt, simi_mean_ft16_, simi_max_ft16_, simi_mfeat_ft16_[0,0]]
    
    if not save:
        return
    

    ##========================================================= save as float32
    rppath = os.path.join(similPath, f'{evt}_ft32.pickle')
    with open(rppath, 'wb') as f:  
        pickle.dump(rltdata, f)
        
    rtpath = os.path.join(similPath, f'{evt}_ft32.txt')
    with open(rtpath, 'w', encoding='utf-8') as f:
        for result in rltdata:
            part = [f"{x:.3f}" if isinstance(x, float) else str(x) for x in result]
            line = ', '.join(part)
            f.write(line + '\n')


    ##========================================================= save as float16        
    rppath_ft16 = os.path.join(similPath, f'{evt}_ft16.pickle')
    with open(rppath_ft16, 'wb') as f:  
        pickle.dump(rltdata_ft16, f)
    
    rtpath_ft16 = os.path.join(similPath, f'{evt}_ft16.txt')
    with open(rtpath_ft16, 'w', encoding='utf-8') as f:
        for result in rltdata_ft16:
            part = [f"{x:.3f}" if isinstance(x, float) else str(x) for x in result]
            line = ', '.join(part)
            f.write(line + '\n')
    

    ##=========================================================== save as uint8        
    rppath_uint8 = os.path.join(similPath, f'{evt}_uint8.pickle')
    with open(rppath_uint8, 'wb') as f:  
        pickle.dump(rltdata_ft16_, f)
    
    rtpath_uint8 = os.path.join(similPath, f'{evt}_uint8.txt')
    with open(rtpath_uint8, 'w', encoding='utf-8') as f:
        for result in rltdata_ft16_:
            part = [f"{x:.3f}" if isinstance(x, float) else str(x) for x in result]
            line = ', '.join(part)
            f.write(line + '\n')