import os,itertools,requests,jsonpath,time,traceback,datetime
import random,sys
import pandas as pd
import uuid as codeuuid
#from search import *
channel=[214,1,217]
cur_dir=os.path.dirname(os.path.abspath(__file__))
file_path=os.path.join(cur_dir,'tempFile')

project_dir=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
data_file_path=os.path.join(project_dir,'dataFile')
def readFile(filename,sheetname=0):
    '''
    :param filename:
    :return:读取csx或xlsx文件
    '''
    houzhui=filename.split('.')[-1]
    if houzhui=='csv':
        df=pd.read_csv(filename, index_col=0,sheetname=sheetname)
    else:
        df=pd.read_excel(filename,sheet_name=sheetname)
    return df
def mergelist(a):
    '''
    :param a:list
    :return: 嵌套list合并成一个
    '''
    t=itertools.chain.from_iterable(a)
    return list(t)
def filePath(filepath,name=''):
    filename=genReportName(name)
    return os.path.join(filepath,filename)
def genReportName(name=''):
    '''
    :param name:
    :return:生成文件名
    '''
    t=round(datetime.datetime.now().timestamp())
    return name+'_'+str(t)+'.xlsx'
def requestsend(uuid,deviceid,searchContent,selectedActivitie,page=1,searchtype='txt',env='online'):
    """
    :param uuid: 用户uuid
    :param deviceid: 设备号id
    :param searchContent: 文本搜索
    :param page: 默认1，搜索页
    :param selectedActivitie: 专题id
    :param type: txt表示文本搜索，否则为专题搜索
    :param env: 环境
    :return:
    """
    if env not in ['test','pro','online']:
        raise Exception('env[{}]只能:test|pro|online'.format(env))
    if env=='online':
        baseurl="http://caesar-gateway.q-gp.com"
    else:
        baseurl="http://open-search-engine.ec-{env}.qg-rc.net".format(env=env) if env=='test'  \
                        else "http://open-search-engine.qg-{env}.qgwebservice.com".format(env=env)
    url=baseurl+"/search"
    header = {
        "XQG-USER-UUID": uuid,
        "content-type": "application/json",
        "XQG-DEVICE-ID": deviceid
    }
    body = {
        "channel": random.sample(channel, 1)[0],
        "userUuid": uuid,
        "deviceId": deviceid,
        "extraParams": {
            "appVersion": "8.8.50",
            "ip": "117.181.115.167",
            "parentPageType": "QGHomeContainerVC,QGSearchContentViewController,QGSearchResultViewController",
            "terminal": "IOS",
            "needAmount": 0,
            "terminalType": 1
        },
        "selectedActivities": [],
        ##文本搜索
        # "searchContent":searchContent ,
        ##专题搜索
        # "selectedActivities":[{
        #     "id": ''.join(random.sample([str(i) for i in range(40)],1)),
        #     "type":2
        # }],
        "sortType": 1,
        "filterInfo": {},
        "flipInfo": {
            "pageNo": page,
            "pageSize": 20
        }
    }
    if searchtype == 'txt': ##文本
        body['searchContent'] = searchContent
    elif searchtype == 'label': ##
        body['selectedActivities'] = [{
            "id": selectedActivitie,  # ''.join(random.sample(','.join('215,214,34,33,32,31,30'),1)),
            "type": 2
        }]
    elif searchtype == 'capt':
        body['selectedActivities'] = [{
            "id": selectedActivitie,  # ''.join(random.sample(','.join('215,214,34,33,32,31,30'),1)),
            "type": 3
        }]
    elif searchtype == 'activity':
        body['selectedActivities'] = [{
            "id": selectedActivitie,  # ''.join(random.sample(','.join('215,214,34,33,32,31,30'),1)),
            "type": 1
        }]
    t = requests.post(url, json=body, headers=header)
    print('搜索词:',searchContent)
    #print(curlify.to_curl(t.request))
    try:
        sku_nos=[]
        sku_templat={"sku_no":"","cid3":"","cid2":"","cid1":"","brandName":""}
        spu_nos = jsonpath.jsonpath(t.json(), '$..skuNo') or ['null']
        cid3  = jsonpath.jsonpath(t.json(), '$..cid3') or ['null']
        cid2  = jsonpath.jsonpath(t.json(), '$..cid1') or ['null']
        cid1  = jsonpath.jsonpath(t.json(), '$..cid2') or ['null']
        brandName  = jsonpath.jsonpath(t.json(), '$..brandName') or ['null']
        for index,i in enumerate(spu_nos):
            sku_templat["sku_no"]=i
            sku_templat["cid3"]=cid3[index]
            sku_templat["cid2"]=cid2[index]
            sku_templat["cid1"]=cid1[index]
            sku_templat["brandName"]=brandName[index]
            sku_nos.append(sku_templat)
        sku_names = jsonpath.jsonpath(t.json(), '$..skuName') or ['null']
        page_size = jsonpath.jsonpath(t.json(), '$..totalPage')[0]
        search_id = jsonpath.jsonpath(t.json(), '$..searchId')[0]
        total_skus=jsonpath.jsonpath(t.json(), '$..totalCount')[0]
        request_time = t.elapsed.total_seconds()
        #tttt=','.join(spu_nos)
        print(sku_nos)
        # with open('sku_result_3.txt', 'a+') as file:
        #     file.write('搜索词:' + searchContent + ";result:" + ','.join(sku_names) + "\n")
        return page_size,sku_nos , str(request_time), search_id,','.join(sku_names),searchContent,total_skus
        #return page_size, ','.join(spu_nos), str(request_time), search_id,','.join(sku_names),searchContent,total_skus
    except:
        traceback.print_exc(limit=2)
        print('搜索接口报错:',searchContent,t.text)


def hotWord(filename,sheetname=0):
    #from tools.fileOperation import readRenameColums
    filepath=os.path.join(data_file_path,filename)
    sheetname=int(sheetname)
    df=readRenameColums(filepath,fcolums=['search_words'],sheetname=sheetname)
    return df

def readRenameColums(filename,fcolums,sheetname=0):
    '''
    :param filename:
    :param fcolums:list，重命名的数据
    :return:列名重命名
    '''
    df=readFile(filename,sheetname)
    try:
        df=df.rename(columns=dict(zip(df.columns,fcolums[0:len(df.columns)])))
    except Exception as e:
        print('重命名的列名数[{}]小于文档中的列名数[{}]，导致无法重命名'.format(len(fcolums),len(df.columns)))
        #print('===接口',traceback.print_exc())
        ##获取错误的堆栈信息
        print("异常的堆栈信息:")
        traceback.format_exc(limit=2)
    return df
def genUuidDeviceid():
    """
    deviced必须随机生成，不然无法统计spu总数。故就算uuid是相同的，deviceid也不能相同
    :return:
    """
    uuid,deviced=codeuuid.uuid4().urn.split(':')[-1],codeuuid.uuid4().urn.split(':')[-1]
    uuid=sys.argv[1]#'c0c27ffb-f2da-4650-8855-2da2191ce772'
    deviced='guiqiuyue_'+str(deviced)
    return uuid,deviced
def totalrun(selectedActivitie=1, type='txt', num=0,isFirstPage=False,sheetname=0,ishotwordrand=1):
    '''
    :param selectedActivitie: 选填
    :param type: 跑文本搜索，还是专题搜索。目前支持：'txt'｜'label'｜'capt'｜'activity'
    :param num: 和ishotwordrand组合，如果ishotwordrand=1，则随机获取搜索词；如果为0，则按照顺序获取搜索词
    :param isFirstPage: 如果只跑第一页，则需要设置为true
    :param sheetname:获取搜索词的sheetname，默认0，第一个工作薄
    :return:
    '''
    timenow=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
    temp=[]
    result_temp={}
    searchContents=hotWord('线上环境搜索热词.xlsx',sheetname=sheetname)['search_words'].apply(lambda x:str(x).strip()).to_list()
    if ishotwordrand:
        random_value=random.Random().randint(0,len(searchContents)-1)
    else:
        random_value=num
    #from tools.publicFun import genUuidDeviceid
    uuid,deviceid=genUuidDeviceid()
    selectedActivitie='2'
    flag=1
    try:
        page_size, spu_nos, \
        request_time, search_id,sku_names,searchContent,total_skus=\
            requestsend(uuid,deviceid,searchContents[random_value],selectedActivitie,flag,type)
        result_temp["nowtime"]=str(timenow)
        result_temp["deviceid"]=deviceid
        result_temp["uuid"]=uuid
        result_temp["searchcontent"]=searchContent
        result_temp["pageno"]=flag
        result_temp["costtime"]=request_time
        #result_temp["skunos"]=spu_nos
        for index,i in enumerate(spu_nos):
            result_temp["skunos"+str(index)]=i
        result_temp['totalSkus']=total_skus
        temp.append(result_temp)
        #file_template=["nowtime","searchcontent","pageno","costtime","deviceid","uuid","skunos"]
        flag+=1
        while  flag<=page_size and not isFirstPage:
            result_temp={}
            page_size, spu_nos, \
            request_time, search_id,sku_names,searchContent= \
                requestsend(uuid,deviceid,searchContents[random_value],selectedActivitie,flag,type)
            result_temp["nowtime"]=timenow
            result_temp["searchcontent"]=searchContent
            result_temp["pageno"]=flag
            result_temp["costtime"]=request_time
            result_temp["deviceid"]=deviceid
            result_temp["uuid"]=uuid
            result_temp["skunos"]=spu_nos
            result_temp['totalSkus']=total_skus
            temp.append(result_temp)
            flag+=1
    #filename=genReportName('searchResult')
        print(temp)
        return temp
    except:
        traceback.print_exc(limit=2)


def allRun(num,isFirstPage=0,sheetname=0,ishotwordrand=1,issleep=1):
    ttemp=[]
    num=int(num)
    for i in range(num):
        print('第[{}]次搜索'.format(str(i)))
        try:
            if issleep:
                time.sleep(0.1)
            temp=totalrun(num=i,isFirstPage=isFirstPage,sheetname=sheetname,ishotwordrand=ishotwordrand)
            ttemp+=temp
            #print(temp)
        except:
            traceback.print_exc(limit=2)
    df=pd.DataFrame(ttemp)
    reportname=filePath(file_path,'searchResult')
    #df['skunos']=df['skunos'].astype('string')
    df.to_excel(reportname,index=0,encoding = 'utf-8',float_format = str)



def analysis(filename=None):
    #temp=defaultdict()
    result=[]
    filename=filename if filename \
        else os.popen("cd {};ls -t |grep -v 'init' |head -1".format(file_path)).read(100)
    filename_path=os.path.join(file_path,filename.strip())
    print('解析文件名：',filename_path)
    df=readFile(filename_path)
    df['searchcontent'].fillna('无效',inplace=True)
    mean_costtime=str(round(df['costtime'].mean(),3)*1000)+'ms'
    count_by=['uuid','deviceid','searchcontent']
    uds=df.groupby(count_by)#['skunos']
    #count_by_skus=count_by.append('skunos')
    #df1=pd.DataFrame(spus,columns=count_by_skus)#['skunos']
    for uuid,deviceid,searchcontent in uds.groups:
        temp={}
        temp['uuid']=uuid
        temp['deviceid']=deviceid
        temp['searchcontent']=searchcontent

        tempskus=df[(df['uuid']==uuid) & (df['deviceid']==deviceid) \
                            &(df['searchcontent']==searchcontent)]['skunos'].to_list()#.__str__()
        temp['costtime']=df[(df['uuid']==uuid) & (df['deviceid']==deviceid) \
                            &(df['searchcontent']==searchcontent)]['costtime'].to_list()
        temp['totalSkus']=mergelist([str(i).split(',') for i in tempskus])
        #print(tempskus)

        temp['isrepeat']=0 if len(temp['totalSkus']) == len(list(set(temp['totalSkus']))) else 1

        temp['curpage_countskus']=len(temp['totalSkus'])

        #print(uuid,deviceid,searchcontent)

        #temppp=1
        temp['countskus']=df[(df['uuid']==uuid) & (df['deviceid']==deviceid) \
                             &(df['searchcontent']==searchcontent)]['totalSkus'].to_list()[0]

        result.append(temp)

    startans=pd.DataFrame(result)

    fist_200=startans[(startans['countskus']<=200)]
    fist_500=startans[(startans['countskus']>200) & (startans['countskus']<=500)]
    fist_1000=startans[(startans['countskus']>500) & (startans['countskus']<=1000)]

    fist1_200_1=[i for i in mergelist(fist_200['costtime'].to_list()) if str(i)>='0.1']
    fist1_200_2=[i for i in mergelist(fist_200['costtime'].to_list()) if str(i)>='0.15']
    fist1_200_3=[i for i in mergelist(fist_200['costtime'].to_list()) if str(i)>='0.2']


    fist1_500_1=[i for i in mergelist(fist_500['costtime'].to_list()) if str(i)>='0.1']
    fist1_500_2=[i for i in mergelist(fist_500['costtime'].to_list()) if str(i)>='0.15']
    fist1_500_3=[i for i in mergelist(fist_500['costtime'].to_list()) if str(i)>='0.2']

    fist1_1000_1=[i for i in mergelist(fist_1000['costtime'].to_list()) if str(i)>='0.1']
    fist1_1000_2=[i for i in mergelist(fist_1000['costtime'].to_list()) if str(i)>='0.15']
    fist1_1000_3=[i for i in mergelist(fist_1000['costtime'].to_list()) if str(i)>='0.2']

    print('总请求数:',startans.shape[0],';平均耗时:',mean_costtime)
    print("spu是否有重复数据:",1 if startans[startans['isrepeat']==1].shape[0] else 0)
    print("搜索词spus总数<=200时-->",'耗时大于100ms的总数',len(fist1_200_1),\
          ';耗时大于150ms的总数',len(fist1_200_2),
          ';耗时大于200ms的总数',len(fist1_200_3))

    print("搜索词spus总数<=500&>200时-->",'耗时大于100ms的总数',len(fist1_500_1), \
          ';耗时大于150ms的总数',len(fist1_500_2),
          ';耗时大于200ms的总数',len(fist1_500_3))

    print("搜索词spus总数<=1000&>500时-->",'耗时大于100ms的总数',len(fist1_1000_1), \
          ';耗时大于150ms的总数',len(fist1_1000_2),
          ';耗时大于200ms的总数',len(fist1_1000_3))



    #return result







if __name__ == '__main__':
    # t=hotWord('线上环境搜索热词.xlsx')['search_words'].apply(lambda x:str(x).strip())
    # print(t)
    #print(totalrun(isFirstPage=1))
    isexec= sys.argv[2] ##判断执行接口还是分析文件
    ishotwordrand=0
    sheetname=sys.argv[3] ##xlsx工作簿
    issleep=sys.argv[4]  ##循环执行接口是否需要sleep
    runnum=sys.argv[5]  ##执行接口总数
    print(sys.argv)
    if isexec and isexec!='0':
        allRun(runnum,isFirstPage=1,sheetname=sheetname,ishotwordrand=ishotwordrand,issleep=issleep)
    else:
        print(analysis())
    # a=[['236473224274432', '7188063'],['236473224274432', '7188063']]
    # print(list(itertools.chain.from_iterable(a)))






