package tlv;

import java.util.Objects;

enum TagDataType {StringCp866, StringCp1251, RawData, LittleEndianDWORD, BigEndianDWORD, Complex}

public enum Tag {
    TAG_TTK_CLIENT_MID(0x0001, TagDataType.StringCp1251),
    TAG_TTK_CLIENT_ECR(0x0002, TagDataType.StringCp1251),
    TAG_TTK_CLIENT_ERN(0x0003, TagDataType.StringCp1251),
    TAG_TTK_CLIENT_AMT(0x0004, TagDataType.StringCp1251),
    TAG_TTK_TRX_MODE(0x0008, TagDataType.StringCp1251),
    TAG_TTK_TRACK2(0x0017, TagDataType.StringCp1251),
    TAG_TTK_CLIENT_RRN(0x0018, TagDataType.StringCp1251),
    TAG_TTK_OPER_TYPE(0x001A, TagDataType.StringCp1251),
    TAG_TTK_DEPARTMENT_INDEX(0x5F02, TagDataType.RawData),
    TAG_TTK_LLT_ID(0x5F03, TagDataType.StringCp1251),
    TAG_TTK_UPOS_MESSAGE(0x5F05, TagDataType.StringCp866),
    TAG_TTK_CARD_EXPDATE(0x5F06, TagDataType.StringCp1251),
    TAG_TTK_PILOT_OPER_TYPE(0x5F07,TagDataType.StringCp1251),
    TAG_TTK_CARD_TYPE(0x5F0D, TagDataType.RawData),
    TAG_TTK_REQUEST_ID(0x5F0A, TagDataType.LittleEndianDWORD),
    TAG_TTK_TRX_FLAGS(0x5F0C, TagDataType.BigEndianDWORD),
    TAG_TTK_SERVER_AMT_C(0x5F33, TagDataType.StringCp1251),
    TAG_TTK_ENCDATA(0x5F39, TagDataType.RawData),
    TAG_TTK_CURRENCY(0x001B, TagDataType.StringCp1251),
    TAG_TTK_BUFFER_SIZE(0x003E, TagDataType.StringCp1251),
    TAG_TTK_COMMAND(0x0040, TagDataType.StringCp1251),
    TAG_TTK_DATA(0x0041, TagDataType.StringCp1251),
    TAG_TTK_SERVER_MID(0x0081, TagDataType.StringCp1251),
    TAG_TTK_SERVER_ECR(0x0082, TagDataType.StringCp1251),
    TAG_TTK_SERVER_ERN(0x0083, TagDataType.StringCp1251),
    TAG_TTK_SERVER_AMT(0x0084, TagDataType.StringCp1251),
    TAG_TTK_PAN(0x0089, TagDataType.StringCp1251),
    TAG_TTK_SERVER_TSN(0x008B, TagDataType.StringCp1251),
    TAG_TTK_SERVER_AUT_CODE(0x008C, TagDataType.StringCp1251),
    TAG_TTK_SERVER_DATE(0x008D, TagDataType.StringCp1251),
    TAG_TTK_SERVER_TIME(0x008E, TagDataType.StringCp1251),
    TAG_TTK_ISSUER_NAME(0x008F, TagDataType.StringCp1251),
    TAG_TTK_MERCHANT_ID(0x0090, TagDataType.StringCp1251),
    TAG_TTK_SERVER_RRN(0x0098, TagDataType.StringCp1251),
    TAG_TTK_TERMINAL_ID(0x009D, TagDataType.StringCp1251),
    TAG_TTK_RESPONSE_CODE(0x009B, TagDataType.StringCp1251),
    TAG_TTK_CHEQUE_IN_ASCII(0x009C, TagDataType.StringCp866),
    TAG_TTK_CHEQUE_IN_PDS(0x009E, TagDataType.StringCp1251),
    TAG_TTK_ERROR_TEXT(0xA0, TagDataType.StringCp1251),
    TAG_TTK_APPROVE(0xA1, TagDataType.StringCp1251),
    TAG_TTK_HASH(0xA3, TagDataType.StringCp1251),
    TAG_TTK_IS_OWN(0xA4, TagDataType.StringCp1251),
    TAG_TTK_ERROR_CODE(0xA5, TagDataType.StringCp1251),
    TAG_TTK_STATE_CODE(0x1F00,TagDataType.StringCp1251),
    TAG_TTK_STATE_DATA(0x1F01, TagDataType.StringCp1251),
    TAG_TTK_SERVER_STATE(0x1F70, TagDataType.StringCp1251),
    TAG_TTK_SERVER_MSG(0x1F71, TagDataType.StringCp1251),
    TAG_TTK_TIMEOUT(0x1F7C, TagDataType.StringCp1251),
    //complex ttk tags
    TAG_TTK_EXTRA_DATA(0x0019, TagDataType.Complex),
    //magnbase tags
    TAG_CASHOUT(0xDF50, TagDataType.LittleEndianDWORD),
    TAG_CUR_ID(0x5F2A, TagDataType.LittleEndianDWORD),
    //monitoring tags
    TAGM_IMEI(0xD1, TagDataType.StringCp1251),     /*string. gprs modem imei*/
    TAGM_ICCID(0xD2, TagDataType.StringCp1251),    /*string. iccid of the current active sim card*/
    TAGM_TCPDEVICE(0xD3, TagDataType.RawData);     /*bitmask*/

    private final int tag;
    private final TagDataType type;

    Tag(int item_tag, TagDataType item_type) {
        tag = item_tag;
        type = item_type;
    }

    public int getTag() {
        return tag;
    }

    public TagDataType getDataType(){
        return type;
    }

    public String getName() {
        return this.name();
    }

    public static Tag findTag(int tagExternal) throws Exception {
        for (Tag tag : Tag.values()) {
            if (tag.tag == tagExternal) {
                return tag;
            }
        }
        throw new Exception("Unknown tag: " + String.format("%X", tagExternal));
    }

    public static Tag findTag(String tagExternal) throws Exception {
        for (Tag tag : Tag.values()) {
            if (Objects.equals(tag.name(), tagExternal)) {
                return tag;
            }
        }
        throw new Exception("Unknown tag: " + tagExternal);
    }
}
