package com.lemon.cases;

import com.alibaba.fastjson.JSONPath;
import com.lemon.constants.Constants;
import com.lemon.pojo.API;
import com.lemon.pojo.Case;
import com.lemon.utils.ExcelUtils;
import com.lemon.utils.SqlUtils;
import io.qameta.allure.Step;
import org.apache.commons.lang3.StringUtils;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.math.BigDecimal;
import java.text.DecimalFormat;

/**
 * @program: Lemon
 * @description:
 * @author: ray
 * @create: 2022-11-03 13:57
 **/
public class RechargeDemoCase extends BaseCase {

    @Test(dataProvider = "datas0", description = "充值测试")   // DTO数据传输
    public void testRecharge(API api, Case cas) throws Exception {
        //1、参数化替换
        String params = replace(cas.getParams());
        String sql = replace(cas.getCheckSQL());
        cas.setParams(params);
        cas.setCheckSQL(sql);
        //2、数据库前置查询结果（断言必须在接口执行前后都查询）
        Object beforeSqlResult = SqlUtils.querySingle(cas.getCheckSQL());
        //3、调用接口
        String body = call(api, cas, true);
        //4、断言响应结果，Excel中预期响应数据与实际响应数据进行对比
        Boolean assertResponseFlag = assertResponse(cas, body);
        //5、添加接口响应回写excel内容
        addWBD(Integer.parseInt(cas.getId()), Constants.ACTURL_WRITER_BACK_CELL_NUM, body);
        //6、数据库后置查询结果
        Object afterSqlResult = SqlUtils.querySingle(cas.getCheckSQL());
        //7、数据库断言
        boolean sqlFlag = sqlAssert(cas, beforeSqlResult, afterSqlResult);
        System.out.println("数据库断言结果：" + sqlFlag);
        //8、添加断言回写内容
        String assertContent = (assertResponseFlag && sqlFlag) ? "Pass" : "Fail";
        addWBD(Integer.parseInt(cas.getId()), Constants.ASSERT_RESULT_CELL_NUM, assertContent);
        //9、添加日志


        //10、报表断言

    }

    /**
     * 接口执行之后的sql结果-接口之前之前的sql结果=参数的amount金额
     *
     * @param cas
     * @param beforeSqlResult
     * @param afterSqlResult
     * @return
     */
    @Step("数据库断言，对比充值前后金额")
    public boolean sqlAssert(Case cas, Object beforeSqlResult, Object afterSqlResult) {
        String sql = cas.getCheckSQL();
        //如果sql为空，说明不需要数据库断言
        if (StringUtils.isBlank(sql)) {
            return true;
        } else {
            //注册断言逻辑：前置sql结果为0，后置sql结果为1，其他情况断言失败
            double aValue = Double.parseDouble(afterSqlResult.toString());
            double bValue = Double.parseDouble(beforeSqlResult.toString());
            // 从Excel的某条Case的JSON里获取amount字段
            double amount = Double.parseDouble(JSONPath.read(cas.getParams(), "$.amount").toString());
            // 操作金钱相关数据类型，使用BigDecimal类型
            DecimalFormat df = new DecimalFormat("#.##");// 保留两位小数

            BigDecimal d1 = new BigDecimal(aValue);
            d1.setScale(2, BigDecimal.ROUND_HALF_UP);
            BigDecimal d2 = new BigDecimal(bValue);
            d2.setScale(2, BigDecimal.ROUND_HALF_UP);
            BigDecimal d3 = new BigDecimal(amount);
            d3 = d3.setScale(2, BigDecimal.ROUND_HALF_UP);

            System.out.println("充值前的账户余额bValue：" + bValue);
            System.out.println("充值后的账户余额aValue：" + aValue);
            System.out.println("充值金额amount：" + amount);

            System.out.println("相减：" + d1.subtract(d2));
            if (d1.subtract(d2).equals(d3)) {
                return true;
            } else {
                return false;
            }
        }
    }


    @DataProvider(name = "datas0")
    public Object[][] datas0() {
        //Object[m][n] m代表执行次数，n代表参数个数
        Object[][] datas = {
                {"http://api.lemonban.com/fetureloan/member/register", "{\"mobile_phone\":\"15500110011\",\"pwd\":\"123456\"}"},
                {"http://api.lemonban.com/fetureloan/member/register", "{\"mobile_phone\":\"15500110012\",\"pwd\":\"123456\"}"},
                {"http://api.lemonban.com/fetureloan/member/register", "{\"mobile_phone\":\"15500110013\",\"pwd\":\"123456\"}"},
        };
        return datas;
    }


    @DataProvider(name = "datas1")
    public Object[][] datas1() {
        // 传参apiID
        Object[][] datas = ExcelUtils.getAPIAndCaseByApiId("3");
        return datas;
    }


}
