package com.fear1ess.reyunaditool.adsfinder;

import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;

import com.fear1ess.reyunaditool.HookEntry;
import com.fear1ess.reyunaditool.IDoCommandService;
import com.fear1ess.reyunaditool.MLog;
import com.fear1ess.reyunaditool.OperateCmd;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class PangLeFinder extends Finder  {
    private static String m_appID="";
    private static String m_temp="";
    private static boolean m_flag=false;
    public PangLeFinder(String adsName, String adsClassName, ClassLoader cl, IDoCommandService service) {
        super(adsName, adsClassName, cl, service);
    }
    public void hookAdsApi() {
        hook_doFinal(mAppClassLoader);
        hook_JSON_Put(mAppClassLoader);
    }
    public  void hook_doFinal(ClassLoader classLoader){
        XposedHelpers.findAndHookMethod("javax.crypto.Cipher",
                classLoader, "doFinal",byte[].class,
                new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        super.beforeHookedMethod(param);
                        try{
                            String content= new String((byte[]) param.args[0]);
                            try{
                                JSONObject jsonObject=new JSONObject(content);
                                JSONArray adslots= (JSONArray) jsonObject.get("adslots");
//                                JSONObject item= (JSONObject) adslots.get(0);
                                if( adslots!=null){
//                                    MLog.d("打印原内容："+content);
                                    if((m_temp.hashCode()==content.hashCode())){
                                        return;
                                    }
                                    m_temp=content;
                                    m_flag=true;
                                }
                            }catch (Exception e){

                            }
//                            if(content.contains("\"adslots\":[{\"id\":\"")){
//                                if((m_temp.hashCode()==content.hashCode())){
//                                   return;
//                                }
//                                m_temp=content;
//                                m_flag=true;
////                                JSONObject jsonObject=new JSONObject(content);
////                                String ad_sdk_version=(String) jsonObject.get("ad_sdk_version");
////                                JSONObject app= (JSONObject) jsonObject.get("app");
////                                String appid= (String) app.get("appid");
////                                String package_name= (String) app.get("package_name");
////                                String version_code= (String) app.get("version_code");
////                                String version= (String) app.get("version");
////
////                                JSONArray adslots= (JSONArray) jsonObject.get("adslots");
//////                                MLog.d("adslots-> "+adslots.toString());
////                                JSONArray my_Adslots=new JSONArray();
////                                for (int i = 0; i < adslots.length(); i++) {
////                                    JSONObject item= (JSONObject) adslots.get(i);
////                                    JSONObject object= new JSONObject();
////                                    object.put("id",item.get("id"));
////                                    object.put("adtype",item.get("adtype"));
////                                    my_Adslots.put(object);
////                                }
////
////                                Map<String,String> map = new HashMap<>();
////                                map.put("appid", appid);
////                                map.put("ad_sdk_version", ad_sdk_version);
////                                map.put("package_name", package_name);
////                                map.put("version_code", version_code);
////                                map.put("version", version);
////                                map.put("adslots", my_Adslots.toString());
////                                MLog.d("穿山甲上传数据: "+map.toString());
////                                uploadAdsData(map);
//                            }
                        }catch (Exception e){
                            MLog.d(e.toString());
                        }


                    }
                }
        );
    }

    public  void hook_JSON_Put(ClassLoader classLoader){
        XposedHelpers.findAndHookMethod(JSONObject.class, "put",
                String.class, int.class,
                new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        super.beforeHookedMethod(param);
                       String key= (String) param.args[0];

                       if(key.equals("cypher")){
                           if(!m_flag){
                              return;
                           }
                           m_flag=false;
//                           MLog.d("key= "+param.args[0]+"  "+param.args[1]);
                           JSONObject jsonObject=new JSONObject(m_temp);
                           String ad_sdk_version=(String) jsonObject.get("ad_sdk_version");
                           JSONObject app= (JSONObject) jsonObject.get("app");
                           String appid= (String) app.get("appid");
                           String package_name= (String) app.get("package_name");
                           String version_code= (String) app.get("version_code");
                           String version= (String) app.get("version");

                           JSONArray adslots= (JSONArray) jsonObject.get("adslots");
//                                MLog.d("adslots-> "+adslots.toString());
                           JSONArray my_Adslots=new JSONArray();
                           for (int i = 0; i < adslots.length(); i++) {
                               JSONObject item= (JSONObject) adslots.get(i);
                               JSONObject object= new JSONObject();
                               object.put("id",item.get("id"));
                               object.put("adtype",item.get("adtype"));
                               my_Adslots.put(object);
                           }

                           Map<String,String> map = new HashMap<>();
                           map.put("appid", appid);
                           map.put("ad_sdk_version", ad_sdk_version);
                           map.put("package_name", package_name);
                           map.put("version_code", version_code);
                           map.put("version", version);
                           map.put("adslots", my_Adslots.toString());
                           map.put("cypher", String.valueOf(param.args[1]));
                           MLog.d("穿山甲上传数据: "+map.toString());
                           uploadAdsData(map);

                       }
                    }
                });

    }


    public void uploadAdsData(Map<String,String> map){
        //ad map to global ads map
        adsMap.put(mAdsName, map);


        if(isServiceBound == false){
            mRemainAdsDataList.add(map);
            Log.d(TAG, "uploadAdsData failed, service is not bound" );
            return;
        }

        try {
            JSONObject adsDataJson = new JSONObject();
            for(Map.Entry<String,String> entry : map.entrySet()){
                adsDataJson.put(entry.getKey(),entry.getValue());
            }
            JSONObject jo2 = new JSONObject();
            jo2.put(mAdsName, adsDataJson);
//            JSONObject jo3 = new JSONObject();
            jo2.put("app_id", HookEntry.processName);
//            jo3.put("data",jo2);
            String uploadData = jo2.toString();
            Log.d(TAG, "uploadAdsData: " + uploadData);
            MLog.d("uploadAdsData: " + uploadData);
            String res = mDoCommandService.doCommand(OperateCmd.UPLOAD_ADSDK_DATA, uploadData);

            updateAdsDataState(mAdsName);
            FinderUtils.uploadAdsSdkExistsState(mDoCommandService, 32, 32);
            if(res.equals("success")){
                Log.d(TAG, "uploadAdsData success");
            }
        } catch (RemoteException | JSONException e) {
            e.printStackTrace();
        }
    }


    private void hook_AppID(ClassLoader classLoader){
        XposedHelpers.findAndHookMethod("com.bytedance.sdk.openadsdk.TTAdConfig",
                classLoader, "setAppId",String.class,
                new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        super.beforeHookedMethod(param);
                        m_appID= (String) param.args[0];
                        MLog.d( "beforeHookedMethod: 穿山甲APPID: "+m_appID);
                    }
                }
        );
    }


    private void hook_SlotID(ClassLoader classLoader){
        XposedHelpers.findAndHookMethod("com.bytedance.sdk.openadsdk.AdSlot$Builder",
                classLoader, "setCodeId",String.class,
                new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        super.beforeHookedMethod(param);
                        String slotID= (String) param.args[0];
                        Map<String,String> map = new HashMap<>();
                        if(TextUtils.isEmpty(m_appID)){
                            m_appID="error";
                        }
                        map.put("appID", m_appID);
                        map.put("slotID", slotID);
                        MLog.d( "beforeHookedMethod: 上传的数据: "+map.toString());
                        uploadAdsData(map);
                    }
                }
        );
    }
}
