package com.beanit.asn1dsrc.util;

import com.beanit.asn1bean.ber.types.BerGeneralizedTime;
import com.beanit.asn1bean.ber.types.BerInteger;
import com.beanit.asn1bean.ber.types.BerOctetString;
import com.beanit.asn1bean.ber.types.string.BerUTF8String;
import com.beanit.asn1dsrc.dsrc.HeaderOptions;
import com.beanit.asn1dsrc.dsrc.PDUs;
import com.beanit.asn1dsrc.dsrc.Time;
import com.beanit.asn1dsrc.enums.ePdusPr;
import com.its.app.utils.SysUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.Calendar;

@Slf4j
public final class DsrcAsn1Utils {

    public static Time getTime() {
        Time tm = new Time();
        Time.TimeSecondFractions tmFac = new Time.TimeSecondFractions();
        Time.TimeTimezone        tmZon = new Time.TimeTimezone();

        Calendar currTm = Calendar.getInstance();

        tm.setTimeYearQty(new BerInteger(currTm.get(Calendar.YEAR)));
        tm.setTimeMonthQty(new BerInteger(currTm.get(Calendar.MONTH)+1));
        tm.setTimeDayQty(new BerInteger(currTm.get(Calendar.DATE)));
        tm.setTimeHourQty(new BerInteger(currTm.get(Calendar.HOUR_OF_DAY)));
        tm.setTimeMinuteQty(new BerInteger(currTm.get(Calendar.MINUTE)));
        tm.setTimeSecondQty(new BerInteger(currTm.get(Calendar.SECOND)));

        tmFac.setMilliseconds(new BerInteger(currTm.get(Calendar.MILLISECOND)));
        tm.setTimeSecondFractions(tmFac);

        tmZon.setTimezoneHourQty(new BerInteger(9));    // GMT+9Hour
        tmZon.setTimeMinuteQty(new BerInteger(0));
        tm.setTimeTimezone(tmZon);
        return tm;
    }
    public static Time getRegisterStartTime() {
        Time tm = new Time();
        Time.TimeSecondFractions tmSecond = new Time.TimeSecondFractions();
        tmSecond.setDeciSeconds(new BerInteger(0));

        Time.TimeTimezone tmZone = new Time.TimeTimezone();
        tmZone.setTimezoneHourQty(new BerInteger(9));
        tmZone.setTimeMinuteQty(new BerInteger(0));

        tm.setTimeYearQty(new BerInteger(2022));
        tm.setTimeMonthQty(new BerInteger(1));
        tm.setTimeDayQty(new BerInteger(1));
        tm.setTimeHourQty(new BerInteger(0));
        tm.setTimeMinuteQty(new BerInteger(0));
        tm.setTimeSecondQty(new BerInteger(0));
        tm.setTimeSecondFractions(tmSecond);
        tm.setTimeTimezone(tmZone);
        return tm;
    }
    public static Time getRegisterEndTime() {
        Time tm = new Time();
        Time.TimeSecondFractions tmSecond = new Time.TimeSecondFractions();
        tmSecond.setDeciSeconds(new BerInteger(0));

        Time.TimeTimezone tmZone = new Time.TimeTimezone();
        tmZone.setTimezoneHourQty(new BerInteger(9));
        tmZone.setTimeMinuteQty(new BerInteger(0));

        tm.setTimeYearQty(new BerInteger(2099));
        tm.setTimeMonthQty(new BerInteger(12));
        tm.setTimeDayQty(new BerInteger(31));
        tm.setTimeHourQty(new BerInteger(0));
        tm.setTimeMinuteQty(new BerInteger(0));
        tm.setTimeSecondQty(new BerInteger(0));
        tm.setTimeSecondFractions(tmSecond);
        tm.setTimeTimezone(tmZone);
        return tm;
    }

    //public static HeaderOptions getHeaderOptions(String senderText, String localIpAddress, BerUTF8String remoteText, BerOctetString remoteIpAddress) {
    public static HeaderOptions getHeaderOptions(BerUTF8String senderText, BerUTF8String localIpAddress, BerUTF8String remoteText, BerOctetString remoteIpAddress) {
        HeaderOptions hdrOpts = new HeaderOptions();

        //hdrOpts.setDatexOriginText(new BerUTF8String(senderText));
        //hdrOpts.setDatexOriginAddressLocation(new BerUTF8String(localIpAddress));
        //hdrOpts.setDatexSenderText(new BerUTF8String(senderText));
        //hdrOpts.setDatexSenderAddressLocation(new BerUTF8String(localIpAddress));
        hdrOpts.setDatexOriginText(senderText);
        hdrOpts.setDatexOriginAddressLocation(localIpAddress);
        hdrOpts.setDatexSenderText(senderText);
        hdrOpts.setDatexSenderAddressLocation(localIpAddress);

        hdrOpts.setDatexDestinationText(remoteText);
        hdrOpts.setDatexDestinationAddressLocation(remoteIpAddress);
        hdrOpts.setDatexDataPacketTime(DsrcAsn1Utils.getTime());

        return hdrOpts;
    }
    public static HeaderOptions getDefaultOptions() {
        HeaderOptions hdrOpts = DsrcAsn1Utils.getHeaderOptions(
                new BerUTF8String("DSRC Center Unit"),
                new BerUTF8String("DSRC Center Unit"),
                new BerUTF8String("DSRC Main Control Unit"),
                new BerUTF8String("DSRC Main Control Unit"));

        return hdrOpts;
    }

    public static HeaderOptions swapHeaderOptions(HeaderOptions options) {
        HeaderOptions hdrOpts = new HeaderOptions();

        hdrOpts.setDatexOriginText(options.getDatexDestinationText());
        hdrOpts.setDatexOriginAddressLocation(options.getDatexDestinationAddressLocation());
        hdrOpts.setDatexSenderText(options.getDatexDestinationText());
        hdrOpts.setDatexSenderAddressLocation(options.getDatexDestinationAddressLocation());
        hdrOpts.setDatexDestinationText(options.getDatexSenderText());
        hdrOpts.setDatexDestinationAddressLocation(options.getDatexSenderAddressLocation());
        hdrOpts.setDatexDataPacketTime(DsrcAsn1Utils.getTime());

        return hdrOpts;
    }

    public static BerGeneralizedTime getBerGeneralizedTime() {
        return new BerGeneralizedTime(SysUtils.getSysTime());
    }
    public static ePdusPr getPduChoice(PDUs pdus) {
        if (pdus.getLogin() != null) return ePdusPr.PDUs_PR_login;
        if (pdus.getFred() != null) return ePdusPr.PDUs_PR_fred;
        if (pdus.getSubscription() != null) return ePdusPr.PDUs_PR_subscripiton;
        if (pdus.getAccept() != null) return ePdusPr.PDUs_PR_accept;
        if (pdus.getPublication() != null) return ePdusPr.PDUs_PR_publication;
        if (pdus.getTransferDone() != null) return ePdusPr.PDUs_PR_transfer_done;
        if (pdus.getDatexInitiateNull() != null) return ePdusPr.PDUs_PR_datex_Initiate_null;
        if (pdus.getLogout() != null) return ePdusPr.PDUs_PR_logout;
        if (pdus.getTerminate() != null) return ePdusPr.PDUs_PR_terminate;
        if (pdus.getReject() != null) return ePdusPr.PDUs_PR_reject;
        return ePdusPr.PDUs_PR_NOTHING;
    }

    public static int getPduChoiceId(PDUs pdus) {
        if (pdus.getLogin() != null) return ePdusPr.PDUs_PR_login.getValue();
        if (pdus.getFred() != null) return ePdusPr.PDUs_PR_fred.getValue();
        if (pdus.getSubscription() != null) return ePdusPr.PDUs_PR_subscripiton.getValue();
        if (pdus.getAccept() != null) return ePdusPr.PDUs_PR_accept.getValue();
        if (pdus.getPublication() != null) return ePdusPr.PDUs_PR_publication.getValue();
        if (pdus.getTransferDone() != null) return ePdusPr.PDUs_PR_transfer_done.getValue();
        if (pdus.getDatexInitiateNull() != null) return ePdusPr.PDUs_PR_datex_Initiate_null.getValue();
        if (pdus.getLogout() != null) return ePdusPr.PDUs_PR_logout.getValue();
        if (pdus.getTerminate() != null) return ePdusPr.PDUs_PR_terminate.getValue();
        if (pdus.getReject() != null) return ePdusPr.PDUs_PR_reject.getValue();
        return ePdusPr.PDUs_PR_NOTHING.getValue();
    }

    public static int getObjectId(int[] endApplicationMessageId) {
        //    return ((arc[3] * 100) + (arc[4] * 10) + arc[5]);
        return (endApplicationMessageId[endApplicationMessageId.length - 3]) * 100 +
               (endApplicationMessageId[endApplicationMessageId.length - 2]) * 10 +
               (endApplicationMessageId[endApplicationMessageId.length - 1]);
    }

}
