# coding=utf-8

# 用途: 用于记录基础逻辑函数
# 创建人: hanhandi
# 创建时间: 2022/11/3

import IPy
import re
import logging
import json
import threading

# 将一个列表,分成n个一组的列表组
def split_list_average_n(list, step):
    return [list[i:i+step] for i in range(0,len(list),step)]


'''*********************************************************************
 * 函数名称:checkip
 * 函数描述:判断输入ip的版本以及合法性
 * 输入参数:address
 * 输出参数:
 *         4: ipv4
 *         6: ipv6
 *         -1: 非法
 * 返 回 值:正常:=0,异常:<0
 * 示例:
 * print(checkip('127.0.0.1'))           ->4
 * print(checkip('::1'))                 ->6
 * print(checkip('255.256.257.258'))     ->-1
 *********************************************************************'''
def checkip(address):
    try:
        version = IPy.IP(address).version()
        if version == 4:
            return 4
        elif version == 6:
            return 6
        else:
            return -1
    except Exception as e:
        return -1

# 判断一个ip是否是ipv6版本
def ipv6_check(addr):
    '''
    Returns True if the IPv6 address (and optional subnet) are valid, otherwise
    returns False.
    '''
    ip6_regex = (
                r'(^(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}$)|'
                r'(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6}\Z)|'
                r'(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}\Z)|'
                r'(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}\Z)|'
                r'(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}\Z)|'
                r'(\A([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}\Z)|'
                r'(\A([0-9a-f]{1,4}:){1,6}(:[0-9a-f]{1,4}){1,1}\Z)|'
                r'(\A(([0-9a-f]{1,4}:){1,7}|:):\Z)|(\A:(:[0-9a-f]{1,4}){1,7}\Z)|'
                r'(\A((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|'
                r'(\A(([0-9a-f]{1,4}:){5}[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|'
                r'(\A([0-9a-f]{1,4}:){5}:[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|'
                r'(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|'
                r'(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,3}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|'
                r'(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,2}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|'
                r'(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,1}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|'
                r'(\A(([0-9a-f]{1,4}:){1,5}|:):(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|'
                r'(\A:(:[0-9a-f]{1,4}){1,5}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)')
    return bool(re.match(ip6_regex, addr,flags=re.IGNORECASE))    

# 将多个dict合成一个大dict
def merge_dicts(*dict_args):
        """
        Given any number of dicts, shallow copy and merge into a new dict,
        precedence goes to key value pairs in latter dicts.
        """
        result = {}
        for dictionary in dict_args:
            result.update(dictionary)
        return result

# 获取两个list的差集
def list_difference(list1, list2):
    set1 = set(list1)
    set2 = set(list2)
    diff = set1.difference(set2)
    return list(diff)

# 获取日志文件的句柄
def get_logger(logger_name, log_file, level=logging.INFO):
    logger = logging.getLogger(logger_name)
    formatter = logging.Formatter('%(asctime)s : %(message)s', "%Y-%m-%d %H:%M:%S")
    fileHandler = logging.FileHandler(log_file, mode='a')
    fileHandler.setFormatter(formatter)

    logger.setLevel(level)
    logger.addHandler(fileHandler)
    return logger

# 保存json文件
def save_data(data, data_path):
    json.dump(data, open(data_path, 'w', encoding='utf-8'), ensure_ascii=False, indent=2, default=lambda obj: obj.__dict__)

'''
判断是否输入的ip是否为ipv4与ipv6混合,这里的混合有两种:
1、ip本身为v4、v6混合
2、一些ip本身为v4,但是机器具有ipv6地址,一些ip机器为ipv4机器,也算混合
'''
def judge_ip_single(ip_list, machine_type):
    # 0、判空
    if len(ip_list) == 0:
        return True
    # 1、判断ip格式本身为v4、v6混合
    v4_list_count = 0
    v6_list_count = 0
    for ip in ip_list:
        if checkip(ip) == 4:
            v4_list_count += 1
        elif checkip(ip) == 6:
            v6_list_count += 1
        else: # 异常ip
            return False 
        if (v4_list_count > 0 and v6_list_count > 0):
            return False 
    return True

'''
自我封装的 线程类型
'''
class MyThread(threading.Thread):
    def __init__(self, threadid, func, **kw):
        self.threadid = threadid
        threading.Thread.__init__(self)
        self.func = func
        self.params = kw
        self.result = None

    def run(self):
        self.result = self.func(**self.params)

    def get_result(self):
        return self.result

    def get_threadid(self):
        return self.threadid
        

'''
自我封装的 超时线程Lock
'''
class TimeoutLock(object):
    def __init__(self):
        self._lock = threading.Lock()
    def acquire(self, blocking=True, timeout=-1):
        return self._lock.acquire(blocking, timeout)
    @contextmanager
    def acquire_timeout(self, timeout):
        result = self._lock.acquire(timeout=timeout)
        yield result
        if result:
            self._lock.release()
    def release(self):
        self._lock.release()

# # Usage:
# lock = TimeoutLock()
# with lock.acquire_timeout(3) as result:
#     if result:
#         print('got the lock')
#         # do something ....
#     else:
#         print('timeout: lock not available')
#         # do something else ...