package com.its.app;

import com.its.app.utils.ItsUtils;
import com.its.app.utils.SysUtils;
import com.its.bis.esb.protocol.EsbFrameTail;
import com.its.bis.esb.protocol.EsbReqVmsShortMsg;
import com.its.bis.xnettcp.vms.protocol.enums.eVmsOpCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.jasypt.salt.StringFixedSaltGenerator;
import org.junit.jupiter.api.Test;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;

@Slf4j
//@SpringBootTest(classes = VmsCommServerApplication.class)
public class AgipCommServerApplicationTests {

    @Test
    void jasypt() {
        String encKey = "asdkjfaslkjflkajslfjkajlkf";
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();

        // ==> SimpleStringPBEConfig 사용시 아래 3개 반드시 설정해야함
        config.setPassword(encKey);                                         // 암호화에 사용할 키
        config.setPoolSize(1);                                              // Pool Size
        config.setSaltGenerator(new StringFixedSaltGenerator("fixedSalt")); // 고정으로 암호화(Default: Random)
        //config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        //config.setAlgorithm("PBEWithMD5AndTripleDES");
        config.setAlgorithm("PBEWithMD5AndDES"); // Jasypt 를 이용한 암호화 알고리즘
        config.setProviderName("SunJCE");
        config.setKeyObtentionIterations("10000");
        config.setStringOutputType("base64");
        /*private Boolean proxyPropertySources = false;
        private String bean = "jasyptStringEncryptor";
        private String password;
        private String algorithm = "PBEWithMD5AndDES";
        private String keyObtentionIterations = "1000";
        private String poolSize = "1";
        private String providerName = null;
        //config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        private String saltGeneratorClassname = "org.jasypt.salt.RandomSaltGenerator";
        private String stringOutputType = "base64";*/
        encryptor.setConfig(config);

        String yiits = encryptor.encrypt("adits");
        String rutis = encryptor.encrypt("ryxhdITS@#");
        log.info("{}", yiits);
        log.info("{}", rutis);
    }

    @Test
    void test1() {
        //                 0123 45 67 89 0123
        String testData = "20230102034000";
        log.info("{}", testData.length());
        String sFrom = testData.substring(4,6) + "월" + testData.substring(6,8) + "일 " + testData.substring(8,10) + "시";
        log.info("{}", sFrom);
    }

    @Test
    void test2() {
        String testData = " ";
        log.info("{}", StringUtils.isEmpty(StringUtils.trim(testData)));
    }

    @Test
    void test3() {
        byte b = (byte)0xFF;
        eVmsOpCode opCode = eVmsOpCode.getValue(b);
        log.info("{}, {}", b, opCode);
    }

    @Test
    void crc() {
        //byte[] data = {(byte)0x05, (byte)0x9A, (byte)0x01, (byte)0x01, (byte)0x1A, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x23, (byte)0x28, (byte)0x00, (byte)0x01, (byte)0x23, (byte)0x28, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x02, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x20, (byte)0x00, (byte)0xA0, (byte)0x00, (byte)0x00, (byte)0x0B};
        byte[] data = {(byte)0x10, (byte)0x02,
                (byte)0x00, (byte)0x05, (byte)0x9A, (byte)0x01, (byte)0x01, (byte)0x1A, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x23,
                (byte)0x28, (byte)0x00, (byte)0x01, (byte)0x23, (byte)0x28, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x02,
                (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x20,
                (byte)0x00, (byte)0xA0, (byte)0x00, (byte)0x00, (byte)0x0B,
                (byte)0x10, (byte)0x03, (byte)0x00, (byte)0x04};
//        int arc = Crc16.ARC(data, 2, data.length - 6);
//        log.info("ARC: {}, {}", arc, String.format("%X", arc));
//        int arc1 = VmsDleFramePacket.getCRC16ARC(data, 2, data.length - 6);
//        log.info("ARC: {}, {}", arc1, String.format("%X", arc1));
    }

    @Test
    void hangul() {
        String str = "30km 이하 서행!";
        //default charset 으로 인코딩된 바이트 배열
        byte[] bytes = str.getBytes();
        //인코딩된 바이트 출력

        System.out.print("Default charset encoding: ");
        for(int i=0;i<bytes.length;i++)
            System.out.print(bytes[i]+" ");
        System.out.println();

        //default charset 으로 디코딩된 문자열 출력
        String decoded = new String(bytes);
        System.out.println(decoded);

        System.out.println();
        try {
            //UTF-8로 인코딩된 바이트 배열
            bytes = str.getBytes("UTF-8");
            System.out.print("UTF-8 charset encoding: ");
            for(int i=0;i<bytes.length;i++)
                System.out.print(bytes[i]+" ");
            System.out.println();
            //이 바이트 배열을 default charset 으로 디코딩된 문자열 출력 : charset 이 다르므로 한글이 깨짐.
            decoded = new String(bytes);
            System.out.println(decoded);
            //인코딩된 UTF-8로 디코딩되어 한글이 깨지지 않음.
            decoded = new String(bytes,"UTF-8");
            System.out.println(decoded);
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Test
    void hangul2() {
        String str = "30km 이하 서행!";
        byte[] arr1 = str.getBytes();
        byte[] arr2 = SysUtils.stringToByteArr(str);
        log.error("{}, {}, {}", str.length(), arr1.length, arr2.length);
    }

    @Test
    void getDnldNmbr() {
        log.info("{}", VmsSymbService.getDnldSymbNmbr("60100"));
        log.info("{}", VmsSymbService.getDnldSymbNmbr("80061"));
        log.info("{}", VmsSymbService.getDnldSymbNmbr("80060"));
        log.info("{}", VmsSymbService.getDnldSymbNmbr("80021"));
        log.info("{}", VmsSymbService.getDnldSymbNmbr("8002"));

        log.info("{}", VmsFormService.getDnldFormNo(10013));
        log.info("{}", VmsFormService.getDnldFormNo(10054));
        log.info("{}", VmsFormService.getDnldFormNo(10186));
        log.info("{}", VmsFormService.getDnldFormNo(13));
    }

    String shortToBinaryString(String binary) {
        String result = binary;
        if (result.length() > 16) {
            return result.substring(16, 32);
        }
        if (binary.length() < 16) {
            int cnt = 16 - binary.length();
            String tmp = "";
            for (int ii = 0; ii < cnt; ii++) {
                tmp += "0";
            }
            return tmp + binary;
        }
        return binary;
    }

    @Test
    void crcTest() {
        // 2의 보수(2s complement)
        short n = 10;
        short result = ItsUtils.orgToTwoComplement(n);
        String binary = ItsUtils.shortToBinaryString(Integer.toBinaryString(result));
        log.info("{}, {}, {}", binary, n, (int)result);

        short result1 = (short) ~n;
        log.info("{}, {}", result1, (result1 + 1));

        // 2s complement 를 원래의 값으로...
        short o = ItsUtils.twoComplementToOrg(result);
        String binary5 = shortToBinaryString(Integer.toBinaryString(o));
        log.info("{}, {}", binary5, o);
    }

    @Test
    void arrayCopy() {
        byte[] facilityIds = new byte[5];

        int facilityIdSize = 15;
        byte[] newFacilityIds = new byte[facilityIdSize];
        if (facilityIds.length < facilityIdSize) {
            facilityIdSize = facilityIds.length;
        }
        System.arraycopy(facilityIds, 0, newFacilityIds, 0, facilityIdSize);
        log.info("{}", facilityIds);
    }

    @Test
    void esbPacket() {
        EsbReqVmsShortMsg vmsShortMsg = new EsbReqVmsShortMsg("ADTRVMS00100001", 1, 2, 24, "가나다123AB CD");
        ByteBuffer byteBuffer = vmsShortMsg.getByteBuffer();
        byte[] packet = byteBuffer.array();
        log.info("{}", SysUtils.byteArrayToHexAscii(packet));
    }


    @Test
    void esbCrcTest() {
        byte[] bbCrc = EsbFrameTail.hexToByteArray("00 20".replace(" ", ""));
        byte[] bb = EsbFrameTail.hexToByteArray("54 52 53 44 46 30 30 39 30 30 36 30 30 56 4d 53 30 30 30 31 32 30 31 36 30 38 32 35 32 30 34 37 30 32 00 00 00 11 02 00 50 00 00 00 0f 30 30 30 36".replace(" ", ""));
        short crc = EsbFrameTail.getCrc(bb);
        log.info("{}", crc);
    }

}
