#! /usr/bin/env python3
import base64
from binascii import a2b_hex
from re import split
import os
import sys
from time import localtime
from Crypto import Cipher
import dbus
import json
import hashlib
import rsa
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_PKCS1_v1_5
import re

#-- coding:utf8 --

def get_machine_id():
    f = open('/etc/machine-id', 'r')
    machine_id=f.read()
    return machine_id[:-1:]

def get_uuid():#仅供自娱自乐
    import uuid
    node = uuid.getnode()
    mac = uuid.UUID(int = node).hex[-12:]
    return mac

def get_mac_address():#返回结果是个列表
    os.system("ls -lrt /sys/class/net/ |grep \"^l\"|awk '{print $9}'>/etc/maclist")
    f = open('/etc/maclist','r')
    mac_name=f.readlines()
    print(mac_name)
    mac_marks=[]
    for mac in mac_name:
        mac_path="/sys/class/net/"+mac[:-1:]+"/address"
        print(mac_path[0:-1:])
        file = open(mac_path,'r')
        mac_mark=file.readline()
        if '00:00:00' not in mac_mark:
            mac_marks+=mac_mark
    mac_address=''.join(mac_marks)
    return mac_address

def get_mac_address1():
    try:
        bus = dbus.SystemBus()
        network_proxy = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager/Devices/2')
        network_interface = dbus.Interface(network_proxy,dbus_interface='org.freedesktop.DBus.Properties')
        mac_address = network_interface.Get('org.freedesktop.NetworkManager.Device.Wired','HwAddress')
        return mac_address
    except:
        return None

def get_mac_address2():
    try:
        bus = dbus.SystemBus()
        networkall_proxy = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager')
        networkall_interface = dbus.Interface(networkall_proxy,dbus_interface='org.freedesktop.NetworkManager')
        alldevices=networkall_interface.GetAllDevices()
        #print(alldevices)
        for device in alldevices:
            print("device name:",device)
            bus = dbus.SystemBus()
            network_proxy = bus.get_object('org.freedesktop.NetworkManager', device)
            network_interface = dbus.Interface(network_proxy,dbus_interface='org.freedesktop.DBus.Introspectable')
            xml_devices=network_interface.Introspect()
            if(re.search('Device.Wired',xml_devices) != None):
                print("device name we need:",device)
                wirednetwork_proxy = bus.get_object('org.freedesktop.NetworkManager', device)
                wirednetwork_interface = dbus.Interface(wirednetwork_proxy,dbus_interface='org.freedesktop.DBus.Properties')
                mac_address = wirednetwork_interface.Get('org.freedesktop.NetworkManager.Device.Wired','HwAddress')
                return mac_address
    except:
        return None

def get_update_time():
    import time 
    localtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 
    return localtime

def get_harddisk_sn():#可以使用命令lsblk -J
    os.system("df -h|grep -w / |awk '{print $1}'>/etc/harddisk")
    file = open('/etc/harddisk','r')
    root_disk=file.readline()
    print(root_disk[:-1:])
    
    os.system("sudo nvme id-ctrl %s| grep sn >/etc/nvme_snmark"%root_disk[:-1:])
    os.system("sudo bash -c \"hdparm -i %s| grep SerialNo > /etc/hd_snmark\""%root_disk[:-1:])
    
    nvme_file=open('/etc/nvme_snmark','r')
    nvme_content=nvme_file.readline()
    nvme_snmark=nvme_content.split(':')

    hd_file=open('/etc/hd_snmark','r')
    hd_content=hd_file.readline()
    hd_snmark=hd_content.split('=')

    if os.path.getsize('/etc/hd_snmark') > 0:
        return hd_snmark[-1][:-1:]
    elif os.path.getsize('/etc/nvme_snmark') >0:
        return nvme_snmark[-1][1:-5:]
    else:
        return None

def get_harddisk_sn1():
    os.system("df -h|grep -w / |awk '{print $1}'>/etc/harddisk")
    file = open('/etc/harddisk','r')
    root_disk=file.readline()
    disk=root_disk[:-1:].split('/')
    try:
        bus = dbus.SystemBus()
        path='/org/freedesktop/UDisks2/block_devices/'+disk[-1]
        harddisk_proxy = bus.get_object('org.freedesktop.UDisks2', path)
        harddisk_interface = dbus.Interface(harddisk_proxy,dbus_interface='org.freedesktop.DBus.Properties')
        id_information = harddisk_interface.Get('org.freedesktop.UDisks2.Block','Id')
        sn_mark=id_information.split('_')[-1].split('-')[0]
        return sn_mark
    except:
        return None

def get_os_version():
    f = open('/etc/lsb-release', 'r')
    for line in f.readlines():
        if line.strip().startswith('DISTRIB_DESCRIPTION='):
            os_version=line.strip().split('=')
            return os_version[1]

def get_kylin_build():
    f = open('/etc/kylin-build', 'r')
    kylin_build_list=f.readlines()
    build=kylin_build_list[1].split()
    date_list=list(build[1])
    date_list.insert(4,"-")
    date_list.insert(7,"-")
    kylin_build=''.join(date_list)
    return kylin_build

def make_dict():#所有获取的信息合成一个字典
    machine_id=get_machine_id()
    mac_address=get_mac_address2()
    localtime=get_update_time()
    sn_marks=get_harddisk_sn1()
    dict1={}
    tmp= {'machine-id':machine_id,'mac':mac_address[0:-1:],'update-date':localtime,\
        'harddisk-sn':sn_marks}
    dict1['machine-infos']=tmp
    return dict1

def make_json(dict1):
    jsonlist=json.dumps(dict1)#,indent=4
    return jsonlist

def send_ornot(machine_id,applicationName, messageType, information, md5):
    file = open('/etc/machine-id-compare')
    compare = file.read()
    print(compare)
    if compare == None:
        result=send_message(applicationName, messageType, information, md5)
        print('None')
        print('it\'s time to send!!')
        print(result)
        return 0
    elif compare == machine_id[:-1:]:
        print('exit')
        sys.exit(1)
    else:
        result=send_message(applicationName, messageType, information, md5)
        print('yolo!')
        print('it\'s time to send!')
        print(result)
        return 0

def enMd5Base64(dict1):
    try:  
        # 生成MD5 
        strUdInfos = json.dumps(dict1)#.replace(' ','')
        print('strUdInfos:',strUdInfos)
        md5info = hashlib.md5(strUdInfos.encode('utf-8')).hexdigest()
        md5_hex=a2b_hex(md5info)
        print('md5_hex:',md5_hex)
        #RSA公钥加密        
        with open('/usr/share/kylin-update-manager/kylingetinfo/public.pem', 'rb') as publickeyfile:
            publickey = publickeyfile.read()
        rsa_pubkey=RSA.importKey(publickey)
        oaep_pub=PKCS1_OAEP.new(rsa_pubkey)
        print('oaep_pub:',oaep_pub)
        en_MB=oaep_pub.encrypt(md5_hex)
        print('en_MB:',en_MB)
        cipher_text = base64.b64encode(en_MB)#.decode()
    except Exception as err:
        print('enMd5Base64 error:',str(err))
    return cipher_text

def send_message(applicationName, messageType, information, md5):#每次发送成功后还要修改文件'/etc/machine-id-compare'内容
    #调用dbus
    bus = dbus.SystemBus()
    information1=information#.replace(' ','')
    print('hahahahahahaah:',md5)
    send_message_proxy = bus.get_object(
        'com.kylin.daq', '/com/kylin/daq')
    getter_interface = dbus.Interface(
                    send_message_proxy,
                    dbus_interface='com.kylin.daq.interface')
    if getter_interface.sendInfo(applicationName, messageType, information1, md5) == 0 :
        f = open('/etc/machine-id', 'r')
        machine_id=f.read()
        print(machine_id[:-1:])
        file = open('/etc/machine-id-compare', 'w')
        machine_id_compare=file.write(machine_id[:-1:])
    else:
        pass
    return getter_interface.sendInfo(applicationName, messageType, information1, md5)

if __name__ == "__main__":
    dict1=make_dict()
    print(dict1)
    machine_id=get_machine_id()
    jsonlist=make_json(dict1)
    print(jsonlist)
    applicationName='select-information'
    
    information=jsonlist
    messageType='dict'
    md5=enMd5Base64(dict1)
    send_ornot(machine_id,applicationName,messageType,information,md5)