package com.its.app;

import com.its.app.utils.ItsUtils;
import com.its.app.utils.SysUtils;
import com.its.bis.AgipCommServerApplication;
import com.its.bis.dto.Location;
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 org.springframework.boot.test.context.SpringBootTest;

import java.io.UnsupportedEncodingException;

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

    public static double getDistance(double lat1, double lon1, double lat2, double lon2) {
        int EARTH_RADIUS = 6371;
        double dLat = Math.toRadians(lat2 - lat1);
        double dLon = Math.toRadians(lon2 - lon1);

        double a = Math.sin(dLat/2)* Math.sin(dLat/2)+ Math.cos(Math.toRadians(lat1))* Math.cos(Math.toRadians(lat2))* Math.sin(dLon/2)* Math.sin(dLon/2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        double d = EARTH_RADIUS* c * 1000;    // Distance in m
        return d;
    }

    @Test
    void getNearNode() {
//        NodeLinkService nodeLinkService = (NodeLinkService)AppUtils.getBean(NodeLinkService.class);
//        Location from = Location.builder()
//                .mLatitude(128.74352336)
//                .mLongitude(36.56392018)
//                .build();
//        log.error("{}", nodeLinkService.getNearNode(from));
    }

    @Test
    void dist() {
//        private double mLatitude = 0.0;     // 위도, 37.48543554333333
//        private double mLongitude = 0.0;    // 경도, 126.89448518666667

        Location from = Location.builder()
                .mLatitude(128.74352336)
                .mLongitude(36.56392018)
                .build();
        Location to = Location.builder()
                .mLatitude(128.73881251)
                .mLongitude(36.56128759)
                .build();

        log.error("{}", from.distanceTo(to));
        log.error("{}", getDistance(from.getMLatitude(), from.getMLongitude(), to.getMLatitude(), to.getMLongitude()));
    }

    @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);
    }

//[
//    {
//        "tenant": {
//        "entityStatus": null,
//                "regUser": null,
//                "regDate": null,
//                "modUser": null,
//                "modDate": null,
//                "entityId": null,
//                "name": "test2",
//                "alias": "test2",
//                "description": null,
//                "logoType": null,
//                "logo1Token": null,
//                "logo1ImageUrl": null,
//                "logo2Token": null,
//                "logo2ImageUrl": null
//    },
//        "deviceName": "LOADER-VOD-36687",
//            "productName": null,
//            "modelName": null,
//            "deviceIdType": null,
//            "deviceId": "6D-45-C4-08-AA-B6",
//            "deviceToken": "a738fcf994e14d8cbb99e4db244a687c",
//            "deviceStatus": "ACTIVE",
//            "deviceType": "ROVER",
//            "deviceClassification": "A05_ETC",
//            "lastConnectionStatus": "CONNECTED",
//            "lastConnectionDatetime": 1619505455498,
//            "gnssInfo": {
//        "deviceId": "6D-45-C4-08-AA-B6",
//                "deviceTime": 1619505737630,
//                "type": "nmea",
//                "raw": "$GPGGA,064217.63,3729.1261326,N,12653.6691112,E,1,00,1.0,19.203,M,0.000,M,0.0,*4C\r\n$GNRMC,064217.63,A,3729.1261326,N,12653.6691112,E,1.34,250.29,270421,0.0,E,A,V*5F\r\n$GNVTG,250.29,T,,M,1.339,N,2.480,K,D*2C\r\n$GNGST,064217.63,10,1.000,1.000,1.000,0.700,5.960,8.770*61\r",
//                "hertz": 0,
//                "latitude": 37.48543554333333,
//                "longitude": 126.89448518666667,
//                "height": 19.203,
//                "speed": 2.48,
//                "angle": 250.29,
//                "pdop": 0,
//                "fixStatus": "NORMAL",
//                "baseStation": "UNKNOWN",
//                "rmsX": 5.96,
//                "rmsY": 0.7,
//                "rmsZ": 8.77,
//                "ecefX": -3042181.7143300786,
//                "ecefY": 4052617.9642652427,
//                "ecefZ": 3860293.232899369,
//                "satellites": []
//    },
//        "healthInfo": {
//        "deviceId": "6D-45-C4-08-AA-B6",
//                "osFamily": "Raspbian GNU/Linux",
//                "osVersion": "10",
//                "cpuUsage": 14.85,
//                "freeMemory": 697125639,
//                "totalMemory": 970825728,
//                "freeStorage": {
//            "/": 61164593113
//        },
//        "totalStorage": {
//            "/": 62738714624
//        },
//        "temperature": 50.7,
//                "bettery": 72,
//                "networkType": "ETHERNET",
//                "collectedDate": null
//    },
//        "satelliteCount": 0,
//            "carId": null,
//            "carNumber": null,
//            "routeId": null,
//            "runStatus": null
//    }
//]

}
