package com.oqpo.api.util;

import java.util.UUID;

public class UniqUtil {

    private final static String DIGITS_36_LOWER = "0123456789abcdefghijklmnopqrstuvwxyz";
    private final static String DIGITS_36_UPPER = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private final static String DIGITS_64 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ#$";
    private final static String DIGITS_62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private final static String DIGITS_26_LOWER = "abcdefghijklmnopqrstuvwxyz";
    private final static String DIGITS_26_UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private final static String DIGITS_16 = "0123456789ABCDEF";
    private final static String DIGITS_8 = "012345678";

    private static long PRDT_NO_BASE_TIME = 0;
    private static int PRDT_NO_SEQ = 10;

    private static long TRANSMIT_KEY_BASE_TIME = 0;
    private static int TRANSMIT_KEY_SEQ = 10;

    private static String longToBase8(long decimalNumber) {
        long base = 8;
        String tempVal = decimalNumber == 0 ? "0" : "";
        int mod = 0;
        while (decimalNumber != 0) {
            long m = decimalNumber % base;
            mod = (int) m;
            tempVal = DIGITS_8.substring(mod, mod + 1) + tempVal;
            decimalNumber = decimalNumber / base;
        }
        return tempVal;
    }

    private static String longToBase16(long decimalNumber) {
        long base = 16;
        String tempVal = decimalNumber == 0 ? "0" : "";
        int mod = 0;
        while (decimalNumber != 0) {
            long m = decimalNumber % base;
            mod = (int) m;
            tempVal = DIGITS_16.substring(mod, mod + 1) + tempVal;
            decimalNumber = decimalNumber / base;
        }
        return tempVal;
    }

    private static String longToBase26Lower(long decimalNumber) {
        long base = 26;
        String tempVal = decimalNumber == 0 ? "0" : "";
        int mod = 0;
        while (decimalNumber != 0) {
            long m = decimalNumber % base;
            mod = (int) m;
            tempVal = DIGITS_26_LOWER.substring(mod, mod + 1) + tempVal;
            decimalNumber = decimalNumber / base;
        }
        return tempVal;
    }

    private static String longToBase26Upper(long decimalNumber) {
        long base = 26;
        String tempVal = decimalNumber == 0 ? "0" : "";
        int mod = 0;
        while (decimalNumber != 0) {
            long m = decimalNumber % base;
            mod = (int) m;
            tempVal = DIGITS_26_UPPER.substring(mod, mod + 1) + tempVal;
            decimalNumber = decimalNumber / base;
        }
        return tempVal;
    }

    private static String longToBase64(long decimalNumber) {
        long base = 64;
        String tempVal = decimalNumber == 0 ? "0" : "";
        int mod = 0;
        while (decimalNumber != 0) {
            long m = decimalNumber % base;
            mod = (int) m;
            tempVal = DIGITS_64.substring(mod, mod + 1) + tempVal;
            decimalNumber = decimalNumber / base;
        }
        return tempVal;
    }

    private static String longToBase62(long decimalNumber) {
        long base = 62;
        String tempVal = decimalNumber == 0 ? "0" : "";
        int mod = 0;
        while (decimalNumber != 0) {
            long m = decimalNumber % base;
            mod = (int) m;
            tempVal = DIGITS_62.substring(mod, mod + 1) + tempVal;
            decimalNumber = decimalNumber / base;
        }
        return tempVal;
    }

    private static String longToBase36Upper(long decimalNumber) {
        long base = 36;
        String tempVal = decimalNumber == 0 ? "0" : "";
        int mod = 0;

        while (decimalNumber != 0) {
            long m = decimalNumber % base;
            mod = (int) m;
            tempVal = DIGITS_36_UPPER.substring(mod, mod + 1) + tempVal;
            decimalNumber = decimalNumber / base;
        }
        return tempVal;
    }

    private static String longToBase36Lower(long decimalNumber) {
        long base = 36;
        String tempVal = decimalNumber == 0 ? "0" : "";
        int mod = 0;

        while (decimalNumber != 0) {
            long m = decimalNumber % base;
            mod = (int) m;
            tempVal = DIGITS_36_LOWER.substring(mod, mod + 1) + tempVal;
            decimalNumber = decimalNumber / base;
        }
        return tempVal;
    }

    public static String getPrdtNo() { // 상품번호
        long baseTime = System.currentTimeMillis();
        if (PRDT_NO_BASE_TIME == baseTime) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
            }
            PRDT_NO_SEQ++;
        } else {
            PRDT_NO_BASE_TIME = baseTime;
            PRDT_NO_SEQ = 10;
        }
        return longToBase62(Long.parseLong(PRDT_NO_BASE_TIME + "" + PRDT_NO_SEQ));
    }

    public static String getTransmitKey() { //  전송키
        long baseTime = System.currentTimeMillis();
        if (TRANSMIT_KEY_BASE_TIME == baseTime) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
            }
            TRANSMIT_KEY_SEQ++;
        } else {
            TRANSMIT_KEY_BASE_TIME = baseTime;
            TRANSMIT_KEY_SEQ = 10;
        }
        return longToBase36Lower(Long.parseLong(TRANSMIT_KEY_BASE_TIME + "" + TRANSMIT_KEY_SEQ));
    }

    private static long getUniqSeq(long baseTime) {
        if (PRDT_NO_BASE_TIME == baseTime) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
            }
            PRDT_NO_SEQ++;
        } else {
            PRDT_NO_BASE_TIME = baseTime;
            PRDT_NO_SEQ = 10;
        }
        return Long.parseLong(PRDT_NO_BASE_TIME + "" + PRDT_NO_SEQ);
    }

    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 1000; i++) {
            long baseTime = System.currentTimeMillis();
            long nanoTime = getUniqSeq(baseTime);

            System.out.println(UUID.randomUUID().toString() + ", " + baseTime + ", " + nanoTime //
                    + ", [0]" + UniqUtil.longToBase62(nanoTime) //
                    + ", [1]" + UniqUtil.longToBase64(nanoTime) //
                    + ", [2]" + UniqUtil.longToBase36Upper(nanoTime) //
                    + ", [3]" + UniqUtil.longToBase36Lower(nanoTime) //
                    + ", [4]" + UniqUtil.longToBase26Upper(nanoTime) //
                    + ", [5]" + UniqUtil.longToBase26Lower(nanoTime) //
                    + ", [6]" + UniqUtil.longToBase16(nanoTime) //
                    + ", [7]" + UniqUtil.longToBase8(nanoTime) //
            );
        }
    }

}