# -*- coding: utf-8 -*-

import math
import random
import hashlib
import numpy as np
from OUEdisturb import JudgeLocation

def KRRParams(epsilon,layer_node_number):
    """获得KRR法的扰动参数"""
    # epsilon  隐私预算
    # layer_node_number  树中某层结点总个数
    
    ee=pow(math.e,epsilon)
    prob_p = float(ee)/(ee+1)
    prob_q = 1.0/(ee+1)
    
    return [prob_p,prob_q]

def SingleDataDisturb(single_user_data,layer_node_range,krr_params):
    """扰动单个用户数据"""
    # single_user_data 单个用户数据，形式为['x','y']
    # layer_node_range 树中某层所有节点范围，形式为[[a1,b1,c1,d1],[a2,b2,c2,d2],[]]
    # krr_params krr法扰动概率
    
    prob_p=krr_params[0]
    temp_length=len(layer_node_range)
    data_index=JudgeLocation(single_user_data,layer_node_range) # 用户数据在该层的索引位置
    
    temp_number=random.random()
    if temp_number < prob_p:
        noise_single_user_data_index=data_index
    else:
        temp_list=list(range(temp_length))
        del (temp_list[data_index])
        noise_single_user_data_index=random.choice(temp_list)
    
    return noise_single_user_data_index
    
def KRRAllDataDisturb(all_user_data,range_list,layer_number,krr_params):
    """扰动所有用户数据"""
    # all_user_data 所有用户数据列表,形式为[['x','y'],['x','y'],[]]
    # range_list 四分树各层结点范围,[[[a1,b1,c1,d1],[a2,b2,c2,d2]],[[a1,b1,c1,d1],[a2,b2,c2,d2],[]]]
    # layer_number 四分树的高度
    # krr_params OUE法扰动概率
    
    noise_all_user_data=[]
    temp_list=list(range(layer_number))
    del (temp_list[0])  # krr法无法在树的根结点层执行，因此随机选择时去掉该层
    
    for i in all_user_data:
        random_level=random.choice(temp_list)
        noise_single_user_data_index=SingleDataDisturb(i,range_list[random_level],krr_params)
        noise_all_user_data.append([random_level,noise_single_user_data_index])
    
    return noise_all_user_data

