package com.xiaomai.client;


import com.xiaomai.enums.Terminal;
import com.xiaomai.jdbc.dao.DataDao;
import com.xiaomai.jdbc.entity.ApiInfo;
import com.xiaomai.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.Assert;
import org.testng.ITestResult;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Properties;

public class BaseTest extends AbstractTestNGSpringContextTests {

    private static final Log logger = LogFactory.getLog(XMBaseTest.class);
    private static DataDao dataDao;

    public static RestfulClient httpclient = null;
    public static SSLRestfulClient sslhttpclient = null;
    public static OkHttpClient okHttpClient = null;
    public static HashMap<String, String> headers;
    public static IdentityHashMap<String, String> params;


    //    该map 主要用于rest-assured 风格请求参数组装预置对象
    public static Map restParams;
    public static Map miniAppRestParams;
    public static Map restParamsAnother;

    private static String host = null;
    public static String url = null;
    private Properties prop = null;
    public static UtDal dal;
    public static volatile XMAppApi xmAppApi;
    //private static CommonRequestParameters loginInfo;
    public static CommonRequestParameters loginInfo;


    // 支持业务数据方法参数
    public static HashMap<String, String> dataheadrs;
    public static IdentityHashMap<String, String> dataparams;

    public static XMAppApi dataApi;

    private static final Logger LOGGER = LoggerFactory.getLogger(BaseTest.class);

    public BaseTest() {
    }


    @BeforeClass
    public static void beforeClass() {
        httpclient = new RestfulClient();
        sslhttpclient = new SSLRestfulClient();
        okHttpClient = new OkHttpClient();
        xmAppApi = new XMAppApi();
        dal = new UtDal();
        //loginInfo=new CommonRequestParameters();
    }


    /**
     * 测试接口调用API
     */
    @BeforeMethod
    public void beforeTest() {
        // 每次执行测试case 前，初始化公共信息对象
        params = new IdentityHashMap<>();
        restParams = new HashMap();
        miniAppRestParams = new HashMap();
        restParamsAnother = new HashMap();
        dataparams = new IdentityHashMap<>();
        dataApi = new XMAppApi();

        clearApiData(xmAppApi);// 清空上次API调用信息
        headers = new HashMap<String, String>();
        dataPreparation(xmAppApi, headers);
    }


    private void clearApiData(XMAppApi api) {
        api.setApi_request_params(new IdentityHashMap());
        api.setApi_request_data(null);
        api.setApi_request_headers(new HashMap<>());
        api.setApi_response(null);
        api.setApi_traceId(null);
    }


    /**
     * 数据业务方法调用  可选参数userInfos  测试时需要切换端位时传入要登录的user信息
     */
    public void beforeDataRequest(DataUserInfo... userInfos) {

        clearApiData(dataApi);// 清空上次API调用信息

        dataheadrs = new HashMap<String, String>();
        // 默认同端位接口调用， dataApi 使用被测试接口信息里的 登录信息
        dataApi.setLoginUser(xmAppApi.getLoginUser())         // http 接口，测试账号
                .setTerminal(xmAppApi.getTerminal());
        // 支持切换端位调用
        if (userInfos.length > 0) {
            DataUserInfo info = userInfos[0];
            Assert.assertNotNull(info, "userInfos 为空！！！");
            if (!StringUtils.isEmpty(info.getLoginUser())) {
                dataApi.setLoginUser(info.getLoginUser());
            }
            if (!StringUtils.isEmpty(info.getTerminal())) {
                dataApi.setTerminal(info.getTerminal());
            }
        }


        dataPreparation(dataApi, dataheadrs);
    }

    /**
     * 业务API调用专用
     */

    private void dataPreparation(XMAppApi executionApi, HashMap<String, String> executionHeaders) {
        Assert.assertNotNull(executionApi.getApiModule(), "必要的api信息不存在！");
        prop = CommUtil.getconfig();

        dataDao = (DataDao) SpringContextUtil.getBean("dataDao");
        ApiInfo apiInfo = dataDao.getApiInfo(executionApi.getApiModule(), executionApi.getApiName());
        Assert.assertNotNull(apiInfo, "接口信息不存在!");

        executionApi.setRequestParamterTemplate(apiInfo.getRequestParameter());
        executionApi.setApiDesc(apiInfo.getApi_name());

        //        服务器集成测试配置
        String env = System.getenv("env");
        if (StringUtils.isBlank(env)) {
            env = prop.getProperty("env");
        }
        logger.info(env);

        host = prop.getProperty(env);
        //            预置登陆信息
        CommonLoginInfo loginInfoMap = (CommonLoginInfo) SpringContextUtil.getBean("commonLoginInfoMap");
        loginInfo = loginInfoMap.get(executionApi.getLoginUser());
        if (StringUtils.isEmpty(loginInfo.getToken())) {
            CommonLogin common_login = new CommonLogin();
            common_login.login(env, executionApi.getLoginUser(), executionApi.getTerminal());
            loginInfo = loginInfoMap.get(executionApi.getLoginUser());
        }

        // 组装URL
        url = host + apiInfo.getApi_path() + loginInfo.getCommonParam(executionApi.getTerminal());
        executionApi.setUrl(url);
//        业务url
        logger.info("业务请求URL==>>" + url);
//          请求头设置
        if ("B".equals(executionApi.getTerminal())) {
            executionHeaders.put("tenant", loginInfo.getTenant());
            executionHeaders.put("adminId", loginInfo.getAdminId());
            executionHeaders.put("token", loginInfo.getToken());
            executionHeaders.put("user", loginInfo.getUser());
            executionHeaders.put("brandId", loginInfo.getBrandId());
            executionHeaders.put("studioId", loginInfo.getStudioId());
            executionHeaders.put("usertype", "B");
            executionHeaders.put("domain", "FITNESS_ADMIN");

        }else if ("minApp".equals(executionApi.getTerminal())) {
            executionHeaders.put("domain", "FITNESS_MEMBER");
            executionHeaders.put("appId", loginInfo.getWechatAppId());
            executionHeaders.put("user", loginInfo.getUser());
            executionHeaders.put("token", loginInfo.getToken());
        }
        executionHeaders.put("xm-request-source", "xmTest");
        executionHeaders.put("User-Agent", "XMSport/1.0 (com.jiejing.sport; build:1; iOS 15.8.1) Alamofire/5.8.0");
        executionHeaders.put("Accept", "*/*");
        executionHeaders.put("Connection", "Keep-Alive");
        // 接口未设置请求头，则默认为 application/json
       /* if (api.containsKey("apiContentType") || StringUtils.isEmpty(api.getString("apiContentType"))) {
            executionHeaders.put("Content-type", "application/json;charset=utf-8");
        } else {
            executionHeaders.put("Content-type", api.getString("apiContentType"));
        }*/
        if (StringUtils.isEmpty(apiInfo.getApi_contentType())) {
            executionHeaders.put("Content-type", "application/json;charset=utf-8");
        } else {
            executionHeaders.put("Content-type", apiInfo.getApi_contentType());
        }
    }


    @AfterMethod
    public void afterMethod(ITestResult result) {
        result.setAttribute("ApiDesc", xmAppApi.getApiDesc());
        //   请求属性
        result.setAttribute("Url", xmAppApi.getUrl());
        result.setAttribute("RequestParams", xmAppApi.getApi_request_params().toString());
        result.setAttribute("RequestData", xmAppApi.getApi_request_data());
//       测试报告添加caseOwner属性
        result.setAttribute("CaseOwner", dal.getCase_owner());
        result.setAttribute("TraceId", xmAppApi.getApi_traceId());
        if (xmAppApi.getApi_startTime() != null) {
            //        请求开始时间和结束时间
            result.setAttribute("StartTime", new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(xmAppApi.getApi_startTime()));
        }
//        params.add(new BasicNameValuePair("EndTime",new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(xmAppApi.getApi_endTime())));
        Long expendTime = xmAppApi.getApi_requestTime();
        result.setAttribute("ExpendTime", expendTime + "ms");
        result.setAttribute("Response", xmAppApi.getApi_response());


//        打印异常请求
        if (expendTime != null) {
            if (expendTime >= 500 && expendTime <= 1000) {
                LOGGER.warn(xmAppApi.getApiDesc() + "接口请求时间超过500毫秒 = " + expendTime.toString());
            } else if (expendTime > 1000) {
                LOGGER.error(xmAppApi.getApiDesc() + " 接口请求时间超过1秒 = " + expendTime.toString());
            }
        }

    }

    @AfterClass
    public static void afterClass() {
        httpclient.shutDownConnection();
        sslhttpclient.shutDownConnection();
    }
}
