#!/bin/python3
import requests
from requests.exceptions import RequestException
import hashlib
from datetime import datetime
import urllib.parse
import json
import sys
import time
import urllib3
#from http.server import BaseHTTPRequestHandler, HTTPServer
import argparse
parser = argparse.ArgumentParser("ZTE reset tr069")
parser.add_argument("ip", help="Router ip address")
parser.add_argument("username", help="Router username", default="admin")
parser.add_argument("password", help="Router password")
parser.add_argument("--login", help="Login method (multi, single)", default="single")
args = parser.parse_args()
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
s = requests.Session()
class zteRouter:
    def __init__(self, ip, username, password, login):
        self.login = login
        self.ip = ip
        self.protocol = "http"  # default to http
        self.username = username
        self.password = password
        self.try_set_protocol()
        self.referer = f"{self.protocol}://{self.ip}/"
    def try_set_protocol(self):
        protocols = ["http", "https"]
        for protocol in protocols:
            url = f"{protocol}://{self.ip}"
            try:
                response = requests.get(url, timeout=5, verify=False)
                if response.ok:
                    self.protocol = protocol
                    # print(f"{self.ip} is accessible via {protocol}")
                    return
            except RequestException:
                pass  # If RequestException occurs, try the next protocol
        # print(f"Could not determine the protocol for {self.ip}")
    def hash(self, str):
        return hashlib.sha256(str.encode()).hexdigest()
    def get_LD(self):
        header = {"Referer": self.referer}
        payload = "isTest=false&cmd=LD"
        r = s.get(self.referer + f"goform/goform_get_cmd_process?{payload}&_=", headers=header, data=payload, verify=False)
        return r.json()["LD"].upper()
    def getVersion(self):
        header = {"Referer": self.referer}
        payload = "isTest=false&cmd=wa_inner_version"
        r = s.get(self.referer + f"goform/goform_get_cmd_process?{payload}", headers=header, data=payload, verify=False)
        return r.json()["wa_inner_version"]
    def get_AD(self):
        def md5(s):
            m = hashlib.md5()
            m.update(s.encode("utf-8"))
            return m.hexdigest().upper() 
        def sha256(s):
            m = hashlib.sha256()
            m.update(s.encode("utf-8"))
            return m.hexdigest().upper()
        wa_inner_version = self.getVersion()
        hash_function = sha256 # set depending on device, MC7010 md5, 889A sha256
        cr_version = ""  # is empty, is printed on getInfos
        a = hash_function(wa_inner_version + cr_version)
        header = {"Referer": self.referer}
        rd_response = s.get(self.referer + "goform/goform_get_cmd_process?isTest=false&cmd=RD", headers=header, verify=False)
        rd_json = rd_response.json()
        u = rd_json.get("RD", "")
        result = hash_function(a + u)  # Use hash_function here as well
        print("result (hash of a + u):", result)  # Debug print
        return result
    def getCookie(self, username, password, LD, login):
        header = {"Referer": self.referer}
        hashPassword = self.hash(password).upper()
        ztePass = self.hash(hashPassword + LD).upper()
        if login == "multi":
            payload = {
                'isTest': 'false',
                'goformId': 'LOGIN_MULTI_USER',
                'password': ztePass,
                'user': username
            }
        else:
            payload = {
                'isTest': 'false',
                'goformId': 'LOGIN',
                'password': ztePass,
            }           
        r = s.post(self.referer + "goform/goform_set_cmd_process", headers=header, data=payload, verify=False)
        return "stok=" + r.cookies["stok"].strip('\"')
    def getTRInfo(self):
        ip = self.ip
        cookie = self.getCookie(username=self.username, password=self.password, LD=self.get_LD(), login=self.login)
        cmd_url = f"{self.protocol}://{self.ip}/goform/goform_get_cmd_process?multi_data=1&isTest=false&cmd=cr_version%2Ctr069_ServerURL%2Ctr069_CPEPortNo%2Ctr069_ServerUsername%2Ctr069_ServerPassword%2Ctr069_ConnectionRequestUname%2Ctr069_ConnectionRequestPassword%2Cwan_ipaddr%2Ctr069_PeriodicInformEnable%2Ctr069_PeriodicInformInterval%2Ctr069_CertEnable%2Ctr069_DataModule%2Ctr069_Webui_DataModuleSupport"
        headers = {
            "Host": ip,
            "Referer": f"{self.referer}index.html",
            "Cookie": f"{cookie}"
        }
        response = s.get(cmd_url, headers=headers, verify=False)
        return response.text
    def setTRInfo(self):
        ip = self.ip
        cookie = self.getCookie(username=self.username, password=self.password, LD=self.get_LD(), login=self.login)
        headers = {
            "Host": ip,
            "Referer": f"{self.referer}index.html",
            "Cookie": f"{cookie}"
        }
        payload = {
            'isTest': 'false',
            'goformId': 'setTR069Config',
            'AD': self.get_AD()
        }
        response = s.post(self.referer + "goform/goform_set_cmd_process", headers=headers, data=payload, verify=False)
        return response.text
zteInstance = zteRouter(args.ip, args.username, args.password, args.login)
class setInfos():
    gatheredJson = json.loads(zteInstance.getTRInfo())
    print(json.dumps(gatheredJson))
    print(zteInstance.setTRInfo())
if __name__ == "__main__":
    setInfos()