package net.northking.cctp.element.basic.keywords;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSON;
import net.northking.cctp.element.basic.enums.DecipherTypeEnum;
import net.northking.cctp.element.basic.enums.EncipherTypeEnum;
import net.northking.cctp.element.basic.enums.ParamsTypeEnum;
import net.northking.cctp.element.basic.enums.TypeConversionEnum;
import net.northking.cctp.element.core.IExecuteContext;
import net.northking.cctp.element.core.annotation.Autowired;
import net.northking.cctp.element.test.AbstractLibraryTest;
import net.northking.cctp.element.test.SampleExecuteContext;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.testng.annotations.Test;
import org.testng.collections.Lists;

import java.io.File;
import java.io.FileInputStream;
import java.nio.charset.Charset;
import java.util.*;

/**
 * CommonTest
 *
 * @author fengxiang.zhang
 * @since 1.0
 */
public class CommonTest extends AbstractLibraryTest {

    final static String resultName = "result";

    @Autowired
    private Common common;

    @Test
    public void testTypeConversion() {
        IExecuteContext context = new SampleExecuteContext.Builder().build();
        Map<TypeConversionEnum, String> dataMap = new LinkedHashMap<>();
        String n = "5379687246014392895116498275006274738186887068394215651730540326126349212535085822145094486000287148824798274943223944";
        String b = "10001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000";
        String o = "21042104210421042104210421042104210421042104210421042104210421042104210421042104210421042104210421042104210421042104210421042104210";
        String h = "88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888";

        dataMap.put(TypeConversionEnum.num2Binary, n);
        dataMap.put(TypeConversionEnum.num2Octal, n);
        dataMap.put(TypeConversionEnum.num2Hex, n);
        dataMap.put(TypeConversionEnum.binary2Num, b);
        dataMap.put(TypeConversionEnum.octal2Num, o);
        dataMap.put(TypeConversionEnum.hex2Num, h);
        dataMap.put(TypeConversionEnum.str2Hex, "0");

        dataMap.forEach((k, v) -> {
            String result = Common.typeConversion(k.value, v, resultName, context);

            System.out.println(result);
        });
    }

    @Test
    public void testRandom() throws Exception {
        IExecuteContext context = new SampleExecuteContext.Builder().build();
        // [\u6587]{2,5}
        /*FileInputStream is = new FileInputStream(new File("C:\\Users\\YunUser\\Desktop\\test\\正则中文.txt"));
        List<String> list = IOUtils.readLines(is, "utf-8");
        List<String> data = Lists.newArrayList("135[0-9]{8}", "[a-zA-Z]{5,8}123", "\\d{1,5}", list.get(0), list.get(1));
        data.forEach(r -> {
            String result = Common.random(r, resultName, context);
            System.out.println(result);
        });*/
        String regex = "^[\\u4e00-\\u9fa5]";
        //regex = "^\\d{1,5}$";
        String result = Common.random(regex, resultName, context);
        System.out.println(result);
    }

    @Test
    public void testEncipher() {
        IExecuteContext context = new SampleExecuteContext.Builder().build();
        Map<EncipherTypeEnum, String> dataMap = new LinkedHashMap<>();
        dataMap.put(EncipherTypeEnum.base64, "0123456789abcdef");
        dataMap.put(EncipherTypeEnum.md5, "0123456789abcdef");
        dataMap.put(EncipherTypeEnum.crc32, "0123456789abcdef");
        dataMap.put(EncipherTypeEnum.sha, "0123456789abcdef");
        dataMap.put(EncipherTypeEnum.sha224, "0123456789abcdef");
        dataMap.put(EncipherTypeEnum.sha256, "0123456789abcdef");
        dataMap.put(EncipherTypeEnum.sha384, "0123456789abcdef");
        dataMap.put(EncipherTypeEnum.sha512, "0123456789abcdef");
        dataMap.put(EncipherTypeEnum.sm4, "0123456789abcdef");

        String hexKey = Convert.toHex("16*8abcd12345678", Charset.forName("UTF-8"));
        System.out.println(hexKey);
        dataMap.forEach((k, v) -> {
            String result = Common.encipher(k.value, v, "UTF-8", hexKey, resultName, context);
            System.out.println(result);
        });
    }

    @Test
    public void testDecipher() {
        IExecuteContext context = new SampleExecuteContext.Builder().build();
        Map<DecipherTypeEnum, String> dataMap = new LinkedHashMap<>();
        dataMap.put(DecipherTypeEnum.base64, "MDEyMzQ1Njc4OWFiY2RlZg==");
        dataMap.put(DecipherTypeEnum.sm4, "af9209ddca33521473088ca987bf5b0a03333dad5640ca276fc63f16999f7985");

        String hexKey = Convert.toHex("16*8abcd12345678", Charset.forName("UTF-8"));
        System.out.println(hexKey);
        dataMap.forEach((k, v) -> {
            String result = Common.decipher(k.value, v, "UTF-8", hexKey, resultName, context);
            System.out.println(result);
        });
    }

    @Test
    public void testAssign() {
        IExecuteContext context = new SampleExecuteContext.Builder()
                .putVariable("var", "1", "number")
                .putGlobalVariable("var", "2", "number")
                .putVariable("var1", "1abc", "string")
                .build();
        List<String> data = Lists.newArrayList("${var1}", "#{var} + 1 + ${var}");
        data.forEach(r -> {
            Object result = Common.assign(r, resultName, context);
            System.out.println(result);
        });
    }

    @Test
    public void testGetLength() {
        String[] arr = {"测试","长度"};
        Map<String,String> map = new HashMap<>();
        map.put("1","1");
        map.put("2","1");

        String str = "测试,测试";
        String spl = ",";
        int max = 0;
        List s = Arrays.asList(StringUtils.split(str, spl, max));

        Object obj = JSON.toJSON(s);
        String param = obj.toString();
        System.out.println(param);
        IExecuteContext context = new SampleExecuteContext.Builder()
                .build();
        Object result = Common.getLength(param, "2", resultName,context);
        System.out.println(result);
    }

    @Test
    public void testAssertExpression() {
        IExecuteContext context = new SampleExecuteContext.Builder()
                .putVariable("var", "1", "number")
                .putGlobalVariable("var", "2", "number")
                .build();
        List<String> data = Lists.newArrayList("1 <= 2", "#{var} + 1 + ${var} == 4");
        data.forEach(r -> {
            Object result = common.assertExpression(r, context);
            System.out.println(result);
        });
    }

    @Test
    public void testSequence() {
        IExecuteContext context = new SampleExecuteContext.Builder()
                .putVariable("var", "1", "number")
                .build();
        for (int i = 0; i < 15; i++) {
            String result = common.sequenceNo("0", "999999", false, "${var}", context);
            System.out.println(result);
        }
    }

}
