#! /usr/bin/env python
"""
@Author: xiaobaiTser
@Time  : 2023/8/15 0:51
@File  : GithubUtils.py
"""
import os
import sys
import time
from random import randint

try:
    from tkinter.messagebox import showerror, showinfo
except ModuleNotFoundError:
    showinfo = showerror = print
try:
    from requests import get, exceptions
    import dns.resolver
except ModuleNotFoundError:
    if sys.version_info.major == 3 and os.name != "nt":
        os.system("pip3 install requests")
        os.system("pip3 install dnspython")
    else:
        os.system("pip install requests")
        os.system("pip install dnspython")


def get_dns_ips(domain: str = "github.com"):
    # 获取域名的 A 记录
    ips = []
    try:
        answers = dns.resolver.resolve(domain, "A")
        for answer in answers:
            if "0.0.0.0" == answer.to_text():
                ips = get_ip138_ip(domain)
            else:
                ips.append(answer.to_text())
    except dns.resolver.NXDOMAIN:
        raise (f"域名【{domain}】不存在")
    except dns.resolver.NoAnswer:
        raise (f"无法获取【{domain}】的 DNS 解析记录")

    return ips


def get_myssl_ip(domain: str = "github.com"):
    headers = {
        "authority": "myssl.com",
        "accept": "application/json, text/javascript, */*; q=0.01",
        "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
        "cookie": "_ga=GA1.1.473578308.1692038436; Hm_lvt_3eb1b7728282a6055c77885a3ebb8917=1692038436; "
        "_hjSessionUser_427812=eyJpZCI6ImYyMGEyYzhkLTg4YWItNTBkOC05NDJjLTcyYTgxYzA5MmRkMSIsImNyZWF0ZWQiOjE2OTIwMzg0MzU5ODYsImV4aXN0aW5nIjpmYWxzZX0=; "
        "_hjShownFeedbackMessage=true; "
        f"Hm_lpvt_3eb1b7728282a6055c77885a3ebb8917={int(time.time())}; "
        "_ga_BTRWVRDVDJ=GS1.1.1692114929.2.1.1692114973.0.0.0",
        "referer": "https://myssl.com/dns_check.html",
        "sec-ch-ua": '"Not/A)Brand";v="99", "Microsoft Edge";v="115", "Chromium";v="115"',
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": '"Windows"',
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "same-origin",
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.203",
        "x-requested-with": "XMLHttpRequest",
    }

    params = {
        "qtype": "1",
        "host": domain,
        "qmode": "-1",
    }
    try:
        res_cur = get(
            "https://myssl.com/api/v1/tools/dns_query",
            params=params,
            headers=headers,
            timeout=5,
        ).json()
        if "data" in dict(res_cur).keys():
            ips = []
            try:
                ips = [
                    ip["value"]
                    for ip in res_cur["data"]["01"]["answer"]["records"]
                    if ip["value"] != "0.0.0.0"
                ]
            except Exception:
                return ips
            try:
                ips.extend(
                    [
                        ip["value"]
                        for ip in res_cur["data"]["852"]["answer"]["records"]
                        if ip["value"] != "0.0.0.0"
                    ]
                )
            except Exception:
                return ips
            try:
                ips.extend(
                    [
                        ip["value"]
                        for ip in res_cur["data"]["86"]["answer"]["records"]
                        if ip["value"] != "0.0.0.0"
                    ]
                )
            except Exception:
                return ips
            return ips

    except Exception:
        return ["\n"]


def get_ip138_ip(domain: str = "github.com"):
    headers = {
        "Accept": "*/*",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
        "Connection": "keep-alive",
        "Cookie": f"Hm_lvt_9528a85ee34f0781ac55bb6e2c29e7ae=1692031412; "
        f"Hm_lpvt_9528a85ee34f0781ac55bb6e2c29e7ae={int(time.time())}",
        "Referer": f"https://site.ip138.com/{domain}/",
        "Sec-Fetch-Dest": "empty",
        "Sec-Fetch-Mode": "cors",
        "Sec-Fetch-Site": "same-origin",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.203",
        "sec-ch-ua": '"Not/A)Brand";v="99", "Microsoft Edge";v="115", "Chromium";v="115"',
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": '"Windows"',
    }

    params = {
        "domain": domain,
        "time": int(time.time() * 1000),
    }
    try:
        cur_res = get(
            "https://site.ip138.com/domain/read.do",
            params=params,
            headers=headers,
            timeout=5,
        ).json()
        if cur_res["status"]:
            ips = [ip["ip"] for ip in cur_res["data"] if "0.0.0.0" != ip["ip"]]
            return ips
        else:
            return get_myssl_ip(domain)
    except Exception:
        return get_myssl_ip(domain)


def rewrite_hosts(domain: str = "github.com"):
    if sys.platform in ["win32"]:
        HOSTS_PATH = r"C:\Windows\System32\drivers\etc\hosts"
    elif sys.platform in ["linux"]:
        HOSTS_PATH = "/etc/hosts"
    elif sys.platform in ["darwin"]:
        HOSTS_PATH = "/private/etc/hosts"
    else:
        HOSTS_PATH = "C:/Windows/System32/drivers/etc/hosts"
    if domain:
        ips = get_dns_ips(domain)  # list
        ips = list(set(ips))
        LINES = [f"\n{ip}\t{domain}" for ip in ips if ip != "\n" or ip != ""]
        if os.access(HOSTS_PATH, os.R_OK) and os.access(HOSTS_PATH, os.W_OK):
            with open(HOSTS_PATH, "r+", encoding="UTF-8") as fr:
                HOSTS_LINES = fr.readlines()
                fr.close()
            NEW_HOSTS_LINES = [line for line in HOSTS_LINES if line not in LINES]
            NEW_HOSTS_LINES.extend(LINES)
            with open(HOSTS_PATH, "w+", encoding="UTF-8") as fw:
                fw.writelines(NEW_HOSTS_LINES)
                fw.close()
        else:
            showerror("小白警告⚠", "[-] " + HOSTS_PATH + "，文件无【读&写】权限！请赋权后再次尝试本脚本！")
    else:
        showerror("小白警告⚠", "[-] 不能写入空数据！")


def flushDNS(domains: str = "", limiter: str = ","):
    if domains:
        domains = domains.replace("，", ",")
        for domain in domains.split(limiter):
            time.sleep(randint(2, 5))
            rewrite_hosts(domain=domain)
        os.popen("ipconfig /flushdns")
        showinfo("小白提示😀：", f"所有数据均已经写入HOSTS文件且已经刷新DNS缓存\n如果发现有缺失请重新执行脚本即可！")
    else:
        showerror("小白警告⚠", "[-] 至少输入一个域名！")


# if __name__ == '__main__':
#     flushDNS(
#         ','.join(
#             [
#                 'github.com',
#                 'github.global.ssl.fastly.net',
#                 'assets-cdn.github.com',
#                 'raw.githubusercontent.com',
#                 'carla.org'
#             ]
#         ),
#         ','
#     )
