
# 获取 dalao所有关于此token的transfer记录 获取dalao的相关关系 例如 A buy token B sell token A transfer B 认为 A。B有关系 对于transfer 多个地址 路径长的 暂不考虑
from base_class import *
from base_class import BaseVariableFunction
import urllib.parse
import shutil
import random
import json
baseclass = BaseVariableFunction(__file__)

old_print = print


def timestamped_print(*args, **kwargs):
    old_print(datetime.datetime.utcnow().replace(
        microsecond=0), *args, **kwargs)


print = timestamped_print

print('\n'*5)
print(f"{'{:<6}'.format('ENTER')} {baseclass.scriptfilename} ----------------NOTE-----------NOTE---------------")
baseclass.makedirpath(baseclass.dalao_tokentransfer_solanafm_path)


def request_onetime(req_dict_total, key_idx,  loop):
    global is_global_sleep 
    if is_global_sleep:
        return
    requests_dict = req_dict_total.get(key_idx)
    if requests_dict is None:
        return
    elif requests_dict['isrequseting'] == True:
        return
    elif requests_dict['need_remove'] == True:
        print(f"key_idx {key_idx} need_remove\n", end='')
        if req_dict_total.get(key_idx) is not None:
            print(f"remove  {cur_conadd} {key_idx}\n", end='')
            del req_dict_total[key_idx]
        return
    requests_dict['isrequseting'] = True

    cur_conadd = requests_dict["req_params"]["address"]
    print(f"enter key_idx={key_idx} cur_conadd={cur_conadd}\n", end='')

    req_response = None
     
            # # url = "https://api.solana.fm/v0/accounts/Hkx63X6mf8t2fn96dUYGd9t6mfC2cKWAYWnLcza2aHE2/transfers?utcFrom=1719822469&utcTo=1720031899&mint=3psH1Mj1f7yUfaD5gh6Zj7epE8hhrMkMETgv5TshQA4o&page=1"
            # req_dict = {
            #     "req_params": {"address": address, 
            #                    "mint":str_token_address,
            #                    "utcFrom":0,
            #                    "utcTo":99999,
            #                    "page":1
            #                    },

    req_url = f"https://api.solana.fm/v0/accounts/{requests_dict['req_params']['address']}/transfers?utcFrom={requests_dict['req_params']['startrange']}&utcTo={requests_dict['req_params']['endrange']}&mint={requests_dict['req_params']['mint']}&page=1"
 
    
    try:
        req_response = requests.get(
            req_url,timeout=requests_dict['timeout'], headers=baseclass.pick_random_user_agent())
        time.sleep(0.2)

    except Exception as e:
        print(f"cur_conadd= {cur_conadd} errmsg={ str(e)}")
        if (" Max retries exceeded" in str(e)):
            time.sleep(2+random.random())
        requests_dict['timeout'] = 15
        requests_dict['isrequseting'] = False
        return
    requests_dict["req_response"] = req_response
    baseclass.makedirpath(baseclass.dalao_tokentransfer_solanafm_path/str_token_address)
    write_tokens_path_name = baseclass.dalao_tokentransfer_solanafm_path / str_token_address/f"{cur_conadd}.json"
    # 请求结果不成功
    if requests_dict["req_response"].status_code != 200:
        print(
            f"cur_conadd= {cur_conadd} response status_code= {requests_dict['req_response'].status_code}")
        if requests_dict["req_response"].status_code == 429:
            is_global_sleep = True
            time.sleep(2)
            is_global_sleep = False
        elif requests_dict["req_response"].status_code == 400:
            print("error 400 req_url=",req_url )
            raise Exception("400 error")
             
        requests_dict['isrequseting'] = False
        return

    # 如果請求結果為成功
    tokenresponse = json.loads(
        requests_dict["req_response"].text)
    # 結果不正常  continue
    if tokenresponse["status"] != "success":
        print(f"key_idx= {key_idx} response is 200 but status not success")
        requests_dict["remainder_retry_times"] -= 1
        requests_dict['isrequseting'] = False
        if requests_dict["remainder_retry_times"] < 0:
            raise Exception(f"key_idx={key_idx} retrytimes<0")
        return

    # 結果正常 獲取txlist
    txlist = None
    txlist = tokenresponse["results"]
    if (txlist == None or len(txlist) == 0):
        print(f"loop={loop} add={cur_conadd} txlist={txlist}")

        requests_dict["need_remove"] = True
        if req_dict_total.get(key_idx) is not None:
            print(f"remove {cur_conadd} {key_idx}\n", end='')
            del req_dict_total[key_idx]
        requests_dict['isrequseting'] = False
        return

    # requests_dict["offsettimes"] += 1
    # if requests_dict["offsettimes"] == 1:
    #     requests_dict["isfirstreq"] = True
    # else:
    #     requests_dict["isfirstreq"] = False
    # if requests_dict["isfirstreq"] == True:
    #     # 如果是第一次请求 删除过去的csv文件
    #     # 如果有这个csv文件 删除
    #     if os.path.exists(write_tokens_path_name):
    #         write_tokens_path_name.unlink()
    cur_zero_timestamp = txlist[0]['data'][0]["timestamp"]
    cur_last_timestamp = txlist[len(txlist)-1]['data'][0]["timestamp"]
    print(
        f"loop={loop} add={cur_conadd}  range={requests_dict['req_params']['startrange'] } {requests_dict['req_params']['endrange']}  len={len(txlist)} cur_zero_timestamp={cur_zero_timestamp} cur_last_timestamp={cur_last_timestamp}")
 
    if True:
        # 不用在乎数目 只要不为0 就一直请求下去
        # # 如果此次請求結果為最大offset，請求結果不全，如果沒到最大請求次數，繼續請求
        requests_dict["need_remove"] = False
        # 更換 end
        cur_minrange = txlist[len(txlist)-1]["data"][0]["timestamp"]
        cur_maxrange = txlist[0]["data"][0]["timestamp"]

        # 如果没有这个csv文件 直接写入
        cur_file = []
        if not write_tokens_path_name.exists():
            print(f"loop={loop} {cur_conadd} 第一次文件\n", end='')

        else:
            with write_tokens_path_name.open(mode="r") as f:
                cur_file = json.load(f)

        cur_file = cur_file + txlist
        print(f"{cur_conadd} 写入\n", end='')
        with write_tokens_path_name.open(mode='w') as f:
            json.dump(cur_file, f)

        requests_dict["req_params"]["endrange"] = int(
            cur_minrange-1)

        baseclass.judge_req_completed(requests_dict=requests_dict,
                                      key_idx=key_idx, cur_conadd=cur_conadd, req_dict_total=req_dict_total)
        requests_dict['isrequseting'] = False
    return

     



def getonetran(address_list):
    global str_token_address
    global startrange , endrange

    print(f"enter getonetran  ")
    req_dict_total = {}
    number_key_idx = 0
 
   
  
    for address in address_list:
  
        number_key_idx += 1
        key_idx = str(number_key_idx) 
        req_dict = {
            "req_params": {"address": address, 
                            "mint":str_token_address,
                            "startrange":startrange,
                            "endrange":endrange,
                            
                            },
            "timeout": 10,
            "key_idx": key_idx,
            "remainder_retry_times": 3,
            "isrequseting": False,
            "need_remove": False,
        }
        req_dict_total[key_idx] = req_dict

    loop = 0
    while (len(req_dict_total.keys()) > 0):
        loop += 1
        # 獲取可以同步請求的address長度 ，traders 長都可能小於 requests_dict定義的長度
        # grequest_len 為 requests_dict長度和實際tokencontracts長度取最小值
        print(
            f"remainder_address_len :{len(req_dict_total.keys())}")

        temp_split_req_dict_total_list = list(req_dict_total.keys())
        temp_split_req_dict_total_list = temp_split_req_dict_total_list[0:10]

        temp_req_dict_total_keys_list = []
        for key_idx in temp_split_req_dict_total_list:
            temp_req_dict_total_keys_list.append(key_idx)
        i = 0

        for key_idx in temp_req_dict_total_keys_list:
            i += 1
            request_onetime(req_dict_total,  key_idx,   loop)
            time.sleep(0.15)

        time.sleep(0.3)

    return


def get_3trans_byScan(address_list):

 
    print("enter get_3trans_byScan_()")
    contractadd_tokentx_list = copy.deepcopy(address_list)
    getonetran(address_list=contractadd_tokentx_list,
               )

    return


is_global_sleep = False
str_token_address=baseclass.str_token_address

df = pd.read_excel(baseclass.dalao_merge_path /
                  f"buytoken_df_{str_token_address}.xlsx",  dtype=object)

arr_str_dalaoaddress = []
arr_str_dalaoaddress=df["Maker"].drop_duplicates().tolist()
# arr_str_dalaoaddress=arr_str_dalaoaddress[1000:]

df["FirstSwaptime"] = pd.to_datetime(df["FirstSwaptime"] )

min_timestamp = int(df['FirstSwaptime'].min().timestamp() )


print(f"arr_str_dalaoaddress_len= {len(arr_str_dalaoaddress)}")
 

startrange =min_timestamp - 1*3600
endrange = startrange + 30*24*3600

print(f"startrange= {startrange} endrange= {endrange}")
 


get_3trans_byScan(address_list=arr_str_dalaoaddress,
                  )


print(f"{'{:<6}'.format('END')} {baseclass.scriptfilename} ----------------NOTE-----------NOTE---------------")
