package com.izouma.nineth;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.kevinsawicki.http.HttpRequest;
import com.google.common.base.Splitter;
import com.izouma.nineth.config.Constants;
import com.izouma.nineth.domain.*;
import com.izouma.nineth.dto.PageQuery;
import com.izouma.nineth.dto.SandPaySettle;
import com.izouma.nineth.dto.UserWithdraw;
import com.izouma.nineth.service.IdentityAuthService;
import com.izouma.nineth.service.UserService;
import com.izouma.nineth.utils.*;
import com.izouma.nineth.web.BaseController;
import io.ipfs.api.IPFS;
import io.ipfs.api.MerkleNode;
import io.ipfs.api.NamedStreamable;
import io.ipfs.multihash.Multihash;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.codec.EncoderException;
import org.apache.commons.codec.net.URLCodec;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.Range;
import org.apache.commons.text.CaseUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.util.TempFile;
import org.bouncycastle.util.encoders.Base64;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.junit.jupiter.api.Test;
import org.libjpegturbo.turbojpeg.processor.api.ImageProcessException;
import org.libjpegturbo.turbojpeg.processor.api.ImageProcessInfo;
import org.libjpegturbo.turbojpeg.processor.api.ImageProcessor;
import org.libjpegturbo.turbojpeg.processor.impl.ImageProcessorImpl;
import org.libjpegturbo.turbojpeg.processor.utils.ImageProcessorUtils;
import org.pngquant.PngQuant;
import org.reflections.ReflectionUtils;
import org.reflections.Reflections;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.Font;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.IntStream;

import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;

public class CommonTest {
    @Test
    public void getGenericsClass() {
        List<User> data = new ArrayList<>();
        data.add(new User());
        System.out.println(data.get(0).getClass().getSimpleName());
        System.out.println(data.getClass());


        Reflections reflections = new Reflections(this.getClass().getPackage().getName() + ".domain");
        Set<Class<? extends BaseEntity>> allClasses = reflections.getSubTypesOf(BaseEntity.class);
        for (Class<? extends BaseEntity> allClass : allClasses) {
            System.out.println(allClass.getName());
        }
    }

    @Test
    public void getapis() {
        List<Map<String, String>> entities = new ArrayList<>();
        Reflections classReflections = new Reflections(this.getClass().getPackage().getName());
        Set<Class<? extends BaseController>> controllers = classReflections.getSubTypesOf(BaseController.class);
        Set<Class<? extends BaseController>> list = ReflectionUtils
                .getAll(controllers, ReflectionUtils.withAnnotation(RestController.class));
        System.out.println(list);

        for (Class<? extends BaseController> aClass : list) {
            RequestMapping requestMapping = aClass.getAnnotation(RequestMapping.class);
            String baseUrl = requestMapping.value()[0];
            for (Method method : ReflectionUtils.getMethods(aClass, ReflectionUtils.withAnnotation(GetMapping.class))) {
                GetMapping getMapping = method.getAnnotation(GetMapping.class);
                System.out.println(getMapping.value()[0]);
            }
            for (Method method : ReflectionUtils
                    .getMethods(aClass, ReflectionUtils.withAnnotation(PostMapping.class))) {
                PostMapping postMapping = method.getAnnotation(PostMapping.class);
                System.out.println(postMapping.value()[0]);
            }
        }
    }

    @Test
    public void testCaseUtils() {
        System.out.println(CaseUtils.toCamelCase("test_Model", true, '_'));
    }

    @Test
    public void testMeasureText() throws IOException, FontFormatException {
        AffineTransform affinetransform = new AffineTransform();
        FontRenderContext frc = new FontRenderContext(affinetransform, true, true);
        Font font = Font.createFont(Font.TRUETYPE_FONT, this.getClass()
                .getResourceAsStream("/font/SourceHanSansCN-Normal.ttf"));
        System.out.println((int) (font.deriveFont(14f).getStringBounds("aaa", frc).getWidth()));
    }

    @Test
    public void testIdNoRegexp() {
        boolean b = Pattern
                .matches("^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0-2]\\d)|3[0-1])\\d{3}$|^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0-2]\\d)|3[0-1])\\d{3}[0-9xX]$", "32100219950830461X");
        System.out.println(b);
    }

    @Test
    public void tesSms() throws IOException {
        Reflections reflections = new Reflections(this.getClass().getPackage().getName() + ".enums");
        Set<Class<? extends Enum>> entitySet = reflections.getSubTypesOf(Enum.class);
        StringBuilder idxJs = new StringBuilder();
        for (Class<? extends Enum> entity : entitySet) {
            idxJs.append("import ").append(entity.getSimpleName()).append(" from \"./").append(entity.getSimpleName())
                    .append("\";\n");
            StringBuilder str = new StringBuilder("export default {\n");
            for (Enum enumConstant : entity.getEnumConstants()) {
                str.append("    ").append(enumConstant.name()).append(": \"").append(enumConstant.name())
                        .append("\",\n");
            }
            str.append("}");
            Files.write(Paths.get(System.getProperty("user.dir"), "src", "main", "vue", "src", "constants", entity
                    .getSimpleName() + ".js"), str.toString()
                    .getBytes(StandardCharsets.UTF_8), CREATE, TRUNCATE_EXISTING);
            Files.write(Paths.get(System.getProperty("user.dir"), "src", "main", "zmj_mp", "src", "constants", entity
                    .getSimpleName() + ".js"), str.toString()
                    .getBytes(StandardCharsets.UTF_8), CREATE, TRUNCATE_EXISTING);
        }
        idxJs.append("export default {\n");
        for (Class<? extends Enum> entity : entitySet) {
            idxJs.append("    ").append(entity.getSimpleName()).append(": ").append(entity.getSimpleName())
                    .append(",\n");
        }
        idxJs.append("}");
        System.out.println(idxJs.toString());
        Files.write(Paths
                .get(System.getProperty("user.dir"), "src", "main", "vue", "src", "constants", "index.js"), idxJs
                .toString().getBytes(StandardCharsets.UTF_8), CREATE, TRUNCATE_EXISTING);
        Files.write(Paths
                .get(System.getProperty("user.dir"), "src", "main", "zmj_mp", "src", "constants", "index.js"), idxJs
                .toString().getBytes(StandardCharsets.UTF_8), CREATE, TRUNCATE_EXISTING);
    }

    @Test
    public void gen() {
        System.out.println(RandomStringUtils.randomAlphabetic(32));
    }

    @Test
    public void password() {
        String password = new BCryptPasswordEncoder().encode("123456");

        System.out.println(password);
    }

    @SneakyThrows
    @Test
    public void pngquant() {
        PngQuant pngQuant = new PngQuant();
        ImageIO.write(pngQuant
                        .getRemapped(ImageIO.read(new File("/Users/drew/Downloads/2021-11-01-18-07-04JCDfFxKb.HEIC"))),
                "jpg", new File("/Users/drew/Downloads/111.jpg"));
    }

    @SneakyThrows
    @Test
    public void mozjpeg() {
        File out = TempFile.createTempFile("kljasdlkhfasldg", ".jpg");
        ImageProcessor processor = new ImageProcessorImpl();
        ImageProcessInfo processInfo = ImageProcessInfo.fromMap(ImageProcessorUtils.compressImage(processor,
                new File("/Users/drew/Downloads/2020-09-08-17-07-21zwBhaHeQ.jpg"),
                out, 75));
        FileCopyUtils.copy(out, new File("/Users/drew/Desktop/111.jpg"));
        System.out.println(out);
    }

    @Test
    public void thumbnailator() throws IOException, ImageProcessException {
        Thumbnails.of(new File("/Users/drew/Downloads/2021-11-01-17-47-55zMwbSlgJ.jpeg"))
                .size(3000, 3000)
                .outputFormat("jpg")
                .toFile("/Users/drew/Desktop/1.jpg");

        PngQuant pngQuant = new PngQuant();
        ImageIO.write(pngQuant
                        .getRemapped(ImageIO.read(new File("/Users/drew/Desktop/1.jpg"))),
                "jpg", new File("/Users/drew/Desktop/2.jpg"));

        ImageProcessor processor = new ImageProcessorImpl();
        ImageProcessInfo processInfo = ImageProcessInfo.fromMap(ImageProcessorUtils.compressImage(processor,
                new File("/Users/drew/Desktop/1.jpg"),
                new File("/Users/drew/Desktop/3.jpg"), 75));
    }

    @Test
    public void base64() {
        System.out.println(Base64.decode("e6e6vQJYhGmIkcA1pfnsipTovp10wJ"));
    }

    @Test
    public void resolveUrl() {
        try {
            System.out.println(new URLCodec().encode("http://www.baidu.com"));
        } catch (EncoderException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testIPFS() throws IOException {
        IPFS ipfs = new IPFS("121.40.132.44", 5001);
        HttpRequest request = HttpRequest.get("https://awesomeadmin.oss-cn-hangzhou.aliyuncs.com/image/2021-10-21-16-44-52kZqxuwhH.gif");
        File file = File.createTempFile("ipfs", ".tmp");
        request.receive(file);
        NamedStreamable.FileWrapper file1 = new NamedStreamable.FileWrapper(file);
        MerkleNode put = ipfs.add(file1).get(0);
        Multihash multihash = ipfs.pin.add(put.hash).get(0);
        System.out.println(put.hash.toBase58());
        System.out.println(multihash.toBase58());
    }

    @Test
    public void testWin() {
        List<BlindBoxItem> items = new ArrayList<>();
        items.add(BlindBoxItem.builder()
                .name("普通1")
                .total(100)
                .stock(100)
                .build());
        items.add(BlindBoxItem.builder()
                .name("普通2")
                .total(100)
                .stock(100)
                .build());
        items.add(BlindBoxItem.builder()
                .name("稀有1")
                .total(5)
                .stock(5)
                .rare(true)
                .build());
        items.add(BlindBoxItem.builder()
                .name("稀有2")
                .total(5)
                .stock(5)
                .rare(true)
                .build());
        for (int k = 0; k < items.stream().mapToInt(BlindBoxItem::getTotal).sum(); k++) {
            Map<BlindBoxItem, Range<Integer>> randomRange = new HashMap<>();
            int c = 0, sum = 0;
            for (BlindBoxItem item : items) {
                randomRange.put(item, Range.between(c, c + item.getStock()));
                c += item.getStock();
                sum += item.getStock();
            }

            boolean win = false;
            int retry = 0;
            BlindBoxItem winItem = null;
            while (winItem == null) {
                int rand = RandomUtils.nextInt(0, sum + 1);
                for (Map.Entry<BlindBoxItem, Range<Integer>> entry : randomRange.entrySet()) {
                    BlindBoxItem item = entry.getKey();
                    Range<Integer> range = entry.getValue();
                    if (rand >= range.getMinimum() && rand < range.getMaximum()) {
                        int total = items.stream().filter(i -> !i.isRare())
                                .mapToInt(BlindBoxItem::getTotal).sum();
                        int stock = items.stream().filter(i -> !i.isRare())
                                .mapToInt(BlindBoxItem::getStock).sum();
                        if (item.isRare()) {
                            double nRate = stock / (double) total;
                            double rRate = (item.getStock() - 1) / (double) item.getTotal();

                            if (Math.abs(nRate - rRate) < (1 / (double) item.getTotal()) || retry > 1 || rRate == 0) {
                                if (!(nRate > 0.1 && item.getStock() == 1)) {
                                    winItem = item;
                                }
                            } else {
                                retry++;
                            }
                        } else {
                            double nRate = (stock - 1) / (double) total;
                            double rRate = item.getStock() / (double) item.getTotal();

                            if (Math.abs(nRate - rRate) < 0.2 || retry > 1 || nRate == 0) {
                                winItem = item;
                            } else {
                                retry++;
                            }
                        }
                    }
                }
            }
            winItem.setStock(winItem.getStock() - 1);
            System.out.println(winItem.getName() + (winItem.isRare() ? "\t+++" : ""));
        }
    }

    @Test
    public void testGrabFrame() throws IOException {
        FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber("/Users/drew/Downloads/video1627914878375.mp4");
        frameGrabber.start();
        Java2DFrameConverter aa = new Java2DFrameConverter();
        int length = frameGrabber.getLengthInVideoFrames();
        Frame frame = null;
        int i = 0;
        while (frame == null && i < length) {
            frame = frameGrabber.grabKeyFrame();
            i++;
        }
        Objects.requireNonNull(frame);
        BufferedImage thumbBi = aa.convert(frame);
        ImageIO.write(thumbBi, "jpg", new File("/Users/drew/Desktop/1.jpg"));
    }

    @Test
    public void testQuality() throws IOException {
        Thumbnails.of("/Users/drew/Desktop/2021-11-04-11-28-36VAOoasUd.jpeg")
                .size(1000, 1000)
                .outputFormat("jpg")
                .outputQuality(1)
                .toFile("/Users/drew/Desktop/1.jpg");
        Thumbnails.of("/Users/drew/Desktop/2021-11-04-11-28-36VAOoasUd.jpeg")
                .size(1000, 1000)
                .outputFormat("jpg")
                .outputQuality(0.6)
                .toFile("/Users/drew/Desktop/2.jpg");
    }

    @Test
    public void testJwt() {
        String token = Jwts.builder()
                .setClaims(new HashMap<>())
                .setSubject("15077886171")
                .setIssuedAt(new Date())
                .setExpiration(new Date(new Date().getTime() + 10 * 60 * 1000)) //10min
                .signWith(SignatureAlgorithm.HS512, Constants.SMS_TOKEN_SECRET)
                .compact();
        System.out.println(token);
        Claims claims = Jwts.parser()
                .setSigningKey(Constants.SMS_TOKEN_SECRET)
                .parseClaimsJws(token)
                .getBody();
        System.out.println(claims.getSubject());
        System.out.println(claims.getExpiration());
    }

    @Test
    public void testReplace() {
        System.out.println("15077886171".replaceAll("(?<=.{3}).*(?=.{4})", "**"));
    }

    @Test
    public void sfsdf() {
        System.out.println(BigDecimal.valueOf(11111110.5).setScale(2, RoundingMode.HALF_UP).toPlainString());
    }

    @Test
    public void random256() throws NoSuchAlgorithmException {
        String tokenId = TokenUtils.genTokenId();
        System.out.println(tokenId);
        System.out.println(new BigInteger(tokenId, 16));
    }

    @Test
    public void dd() throws IOException {
        String[] arr1 = FileUtils.readFileToString(new File("/Users/drew/Desktop/未命名文件夹 2/111")).split("\n");
        List<String> arr2 = Arrays.asList(FileUtils.readFileToString(new File("/Users/drew/Desktop/未命名文件夹 2/222"))
                .split("\n"));
        for (String s : arr1) {
            if (!arr2.contains(s)) {
                System.out.println(s);
            }
        }
    }

    @Test
    public void jj() {
        final int parallelism = 4;
        ForkJoinPool forkJoinPool = null;
        try {
            forkJoinPool = new ForkJoinPool(parallelism);
            forkJoinPool.submit(() ->
                    // Parallel task here, for example
                    IntStream.range(1, 1_000_000).parallel()
                            .forEach(i -> {
                            })
            );
        } finally {
            if (forkJoinPool != null) {
                forkJoinPool.shutdown();
            }
        }
    }

    @Test
    public void testnewSingleThreadScheduledExecutor() throws InterruptedException {
        ExecutorService service = Executors.newFixedThreadPool(10);
        final int[] c = {0};
        for (int i = 0; i < 1000; i++) {
            service.submit(new Runnable() {
                @SneakyThrows
                @Override
                public void run() {
                    Thread.sleep(300);
                    System.out.println(++c[0]);
                }
            });
        }
        Thread.sleep(20000);
    }

    @Test
    public void testaes() throws Exception {
        String encrypted = "ccd97379f001d47895eb4293144b74f28de4fcf5b56daf4ce73d2db34f381984b2c2260f821593968e387dccdc11713a5b558a571b17aaae3e9e91a0b9dc576e";
        String qs = AESEncryptUtil.decrypt(encrypted);
        System.out.println(qs);
        List<NameValuePair> list = URLEncodedUtils.parse(qs, StandardCharsets.UTF_8);
        System.out.println(JSON.toJSONString(list, SerializerFeature.PrettyFormat));

        final Map<String, String> map = Splitter.on('&').trimResults().withKeyValueSeparator('=').split(qs);
        System.out.println(map);
    }

    @Test
    public void aasdf() {
        System.out.println(new BCryptPasswordEncoder().matches("123456", "$2a$10$hYKQk3SKDqpK2QPDFqGdLekKWFcHs8rvou0hV4TxFy.ylL8PTBo5a"));
    }


    @Test
    public void testBCrypt() {
        BCryptPasswordEncoder encoder1 = new BCryptPasswordEncoder(4);
        BCryptPasswordEncoder encoder2 = new BCryptPasswordEncoder(4);
        String pwd = "$2a$10$oAWnGIHR2Cvc0BsMN7YCtOjvXsBLBygYxiVG3E1fuUmhM3sEOYhQe";

        System.out.println(encoder1.matches("123456", pwd));
        System.out.println(encoder2.matches("123456", pwd));

        System.out.println(encoder1.matches("1234561", pwd));
        System.out.println(encoder2.matches("1234561", pwd));

        long encode1 = 0;
        long match1 = 0;
        for (int i = 0; i < 10; i++) {
            long t = System.currentTimeMillis();
            encoder1.encode("123456");
            encode1 += System.currentTimeMillis() - t;

            t = System.currentTimeMillis();
            encoder1.matches("123456", pwd);
            match1 += System.currentTimeMillis() - t;
        }
        System.out.println("avg encode = " + encode1 / 10 + "ms");
        System.out.println("avg match = " + match1 / 10 + "ms");


        long encode2 = 0;
        long match2 = 0;
        for (int i = 0; i < 10; i++) {
            long t = System.currentTimeMillis();
            encoder2.encode("123456");
            encode2 += System.currentTimeMillis() - t;

            t = System.currentTimeMillis();
            encoder2.matches("123456", pwd);
            match2 += System.currentTimeMillis() - t;
        }
        System.out.println("avg encode = " + encode2 / 10 + "ms");
        System.out.println("avg match = " + match2 / 10 + "ms");
    }


    @Test
    public void testParseToken() {
        long t1 = 0;
        long t2 = 0;
        for (int i = 0; i < 1000; i++) {
            long t = System.currentTimeMillis();
            String token = Jwts.builder()
                    .setClaims(new HashMap<>())
                    .setSubject("a" + i)
                    .setIssuedAt(new Date())
                    .setExpiration(new Date(new Date().getTime() + 10000000))
                    .signWith(SignatureAlgorithm.HS256, "123456")
                    .compact();
            t1 += System.currentTimeMillis() - t;

            System.out.println(token);

            t = System.currentTimeMillis();
            Claims claims = Jwts.parser()
                    .setSigningKey("123456")
                    .parseClaimsJws(token)
                    .getBody();
            System.out.println(claims.getSubject());
            t2 += System.currentTimeMillis() - t;
        }
        System.out.println(t1);
        System.out.println(t2);
        System.out.println(t1 / 1000);
        System.out.println(t2 / 1000);
    }

    @Test
    public void testHashCode() {
        long t = System.currentTimeMillis();

        new PageQuery().hashCode();

        System.out.println(System.currentTimeMillis() - t);
    }

    @Test
    public void testversion() {
        String version = "1.2.321";
        String[] arr = version.split("\\.");
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < arr.length; i++) {
            str.insert(0, String.format("%03d", Integer.parseInt(arr[arr.length - 1 - i])));
        }
        System.out.println(Integer.parseInt(str.toString()));

    }

    @Test
    public void testNumberFormat() {
        DecimalFormat df = new DecimalFormat("000000", DecimalFormatSymbols.getInstance(Locale.US));
        System.out.println(df.format(new BigDecimal("199.11")));       // prints: 001.0
    }

    @Test
    public void testWriteExcel() throws IOException, InvalidFormatException {
        // Creating file object of existing excel file
        File xlsxFile = new File("/Users/drew/Downloads/批量付款到对私银行账户模板的副本.xls");

        InputStream inputStream = getClass().getResourceAsStream("/批量付款到对私银行账户模板.xls");

        //Creating workbook from input stream
        Workbook workbook = WorkbookFactory.create(inputStream);

        //Reading first sheet of excel file
        Sheet sheet = workbook.getSheetAt(0);


        for (int i = 0; i < 100; i++) {
            Row row = sheet.getRow(i + 1);
            if (row == null) {
                row = sheet.createRow(i + 1);
            }
            Optional.ofNullable(row.getCell(1)).orElse(row.createCell(1)).setCellValue("1");
            Optional.ofNullable(row.getCell(2)).orElse(row.createCell(2)).setCellValue("2");
            Optional.ofNullable(row.getCell(3)).orElse(row.createCell(3))
                    .setCellValue(new BigDecimal("1").doubleValue());
        }

        //Close input stream
        inputStream.close();

        FileOutputStream os = new FileOutputStream(xlsxFile);
        workbook.write(os);

        //Close the workbook and output stream
        workbook.close();
    }

    @Test
    public void testSandImport() {
        List<SandPaySettle> failSettleList = EasyExcel.read("/Users/drew/Downloads/0411失败.csv")
                .head(SandPaySettle.class).sheet()
                .doReadSync();
        List<UserWithdraw> withdrawList = EasyExcel.read("/Users/drew/Downloads/0411.xlsx")
                .head(UserWithdraw.class).sheet()
                .doReadSync();
        List<UserWithdraw> failWithdraw = new ArrayList<>();
        for (SandPaySettle sandPaySettle : failSettleList) {
            withdrawList.stream().filter(i -> i.getBankNo().equals(sandPaySettle.getBankNo()))
                    .findAny().ifPresent(failWithdraw::add);
        }

        System.out.println(failSettleList.size());
        System.out.println(failWithdraw.size());
    }

    @Test
    public void match() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
        byte[] byteKey = java.util.Base64.getDecoder()
                .decode(Files.readAllBytes(Path.of("/Users/drew/Downloads/hmpay_app_public_key.txt")));
        PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(byteKey));
        System.out.println(publicKey);
        byte[] bytePriv = java.util.Base64.getDecoder()
                .decode(Files.readAllBytes(Path.of("/Users/drew/Downloads/hmpay_app_private_key.txt")));
        PrivateKey privKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(bytePriv));
        System.out.println(privKey);
    }

    public class Views {
        public class Public {
        }

        public class Internal extends Public {
        }
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Item {
        @JsonView(Views.Public.class)
        public int id;

        @JsonView(Views.Public.class)
        public String itemName;

        @JsonView(Views.Internal.class)
        public String ownerName;
    }

    @Test
    public void testJsonView() throws JsonProcessingException {
        Item item = new Item(2, "book", "John");

        ObjectMapper mapper = new ObjectMapper();
        String result = mapper
                .writerWithView(Views.Internal.class)
                .writeValueAsString(item);

        System.out.println(result);
    }

    @Test
    public void testSet() {
        Set<Tag> set = new HashSet<>();
        set.add(new Tag(1L, "tag1", "tag1"));
        set.add(new Tag(1L, "tag1", "tag1"));
        set.add(new Tag(1L, "tag1", "tag1"));
        System.out.println(set);
    }

    @Test
    public void decrypt() throws Exception {
        System.out.println(AESEncryptUtil.decrypt("3BBC5669B95729554056D247338D3BAECA4483E429514227058BF3503F2D42A0"));
    }

    @Test
    public void auth() {
        IdentityAuthService.validate("熊竹", "15077886171", "321002199408304611");
        IdentityAuthService.validate("熊竹", "15077886171", "321002199408304614");
    }

    @Test
    public void testAge() {
        System.out.println(ChronoUnit.YEARS.between(LocalDate.parse("321002199408304614".substring(6, 14),
                DateTimeFormatter.ofPattern("yyyyMMdd")), LocalDate.now()));
    }

    @Test
    public void patt() {
        Pattern p = Pattern.compile("银行卡已绑定！绑卡ID:(\\d+)");
        Matcher m = p.matcher("银行卡已绑定！绑卡ID:20220602315804717062699846352896");
        if (m.find()) {
            System.out.println(m.group(1));
        }
    }

    @Test
    public void createaccount() {
        JSONObject jsonObject = JSON.parseObject(HttpRequest.get("http://47.107.77.154:10000/api/privateKey?type=2&userName=" + UUID.randomUUID() + "&signUserId="
                + RandomStringUtils.randomAlphabetic(8) + "&appId=1&returnPrivateKey=true").body());
        System.out.println(JSON.toJSONString(jsonObject, true));
    }

    @Test
    public void testOneKey() {
        UmengUtils.getMobile("62b8106188ccdf4b7eaba3e8", "eyJjIjoibEVjUGh6WXhwdE5FTHVjQ1p0XC9TREZuMGpLSzlZenZhblBaeUxPUWFrRlJUaFwvaWdrUFA2NU1GZGFDd3F3cjdZVGlPWXhEOVRnWGx3XG5PbGI5MytnN29aaGFpV24rbmd2Q1MxUE1vem5cLzVIQ1BveEk4WG94Zkd3Nkozc3pjMk95NUdFZjBsak9Qd09nMk1iVDBWRjl3Y05zMFxuc2NScGVTd0VoSXh1elpwZ2c5dk5xQlliN2toNWF0cmRtRHQzanZNTHBjUm5OeCtwMXdKS1wvN1VlYTN4b3FJajhSakRuVnFZVmJrcm1cbmtKSDhkNUxrbEEzSzhXU2pVeEF5bkZlSVRWbGNpRlJHTUhvZTBYM1ppZ0pDa0pQWk80VVFGVktSaWlRcFpQbGVGTEhNOHRpTnlTQ0Ncbm1ESmQ1OEM3eWdmWktcLzJcL1ZUc1ZkdFpYUktcL0FqVjNGbk84QnhTZWZQZjVmZEI0YThJQzE2SVFINW91Y2U3NERRbG96SGVIVjhSMldcbmQzaHFRZVh4UFkwd09mdW51elFGSHRscUxnSXlWUDA2bFRaZ0VYdTZpbjJDWDlSUndpa3RxUU81NkRjYzdCeWEzdXQyN0ZcL0VzUmRjXG5Vc3J3ZjVkNE41K0N6cFlBSlpWZmh4ZUlYMUZUVmJPZmFEcWQ0RUpPSTFnclwvTkpXUW9uSG14cUZvXC81WEM2dGwzSG5lQWZwM3dGejJcbk1qQ3d4aWF1ZTJ6OWVpNXZpb1F6Z0lhTWREckJ0eFFPcDU3RW5sZm50NGF1NG8yNGJSQTBSSzI2THZwRzVEakRiZWRTY2xZVEZSY2tcbjBITlUzUFdiQ1hrPVxuIiwiayI6IlQwd0hqc3JiSlV6XC9YRGNUSDVcL0Q5QkpcLzZaVzZmR1BGckdQcmRjdEZDR1Z0NGtcLzdTTzJ6TGU5dlVcL0JlUitcL0VYcDNTWFlLcWhLYXh2QW1vazZjY3FveGk3aE1xckcySHNwbUxLWEtkXC9CbUlHMHhDUjVPWm42SWJvK1BhU2djWlk0MUJic01zRm9RVmRmYUIrZitTVkdJQU50K2lNdm5SRkJpUXNja1N0SVZFd0hvZFgwVkZwd2xVN1UwRTBER01qclJLclI2eGRsMFlSZURIbTVuN3hqaVppOVg1ZTQzZ1UxYk9GOVwvelJwa2ZVd05sN3g2a0tpS25XQ25TU2FuQjhDbHJiNTZ0Qll2czdcL3pKdDJsYXh6UGVMb0Jielp1N0lLTHlUcnc4ZVwvVlNmaUlPYmI5dVNqeXFLRU12dXNQRHFmNmNlQUpRUzlIcW1nQk0wbWZiOVE9PSIsIm8iOiJBbmRyb2lkIn0=");
    }
}