package net.northking.cctp.element.internal.protocol.socket.cups8583;

import net.northking.cctp.element.core.exception.ComponentRuntimeException;
import net.northking.cctp.element.internal.protocol.socket.cups8583.internal.CsvCupsFieldDefReader;
import net.northking.cctp.element.internal.protocol.socket.cups8583.internal.CupsHeader;
import net.northking.cctp.element.internal.protocol.socket.cups8583.internal.ValueObject;
import org.apache.commons.lang3.StringUtils;

import java.util.TreeMap;

/**
 * CupsRequestMessage
 *
 * @author fengxiang.zhang
 * @since 1.0
 */
public class CupsRequest {

    /**
     * 报文头
     */
    private CupsHeader header;
    /**
     * 报文类型：4位定长数字
     */
    private String messageType;
    /**
     * 报文体
     */
    private TreeMap<String, ValueObject> body = new TreeMap<>(new CsvCupsFieldDefReader.CupsFieldKeyComparator());

    private CupsRequest() {
        this.header = new CupsHeader();
    }

    public CupsRequest addMessageLength(int length) {
        int len = Integer.parseInt(this.header.getTotalMessageLength()) + length;
        if (len > 9999) {
            throw new ComponentRuntimeException("请求报文内容超长");
        }
        this.header.setTotalMessageLength(StringUtils.leftPad(len + "", 4, "0"));
        return this;
    }

    public static CupsRequest withParam(CupsRequestParam param) {
        CupsRequest request = new CupsRequest();
        if (param.isEnableHeaderLength()) {
            request.header.setHeaderLength(CupsHeader.HEADER_TOTAL_BYTE_NUM);
        }
        request.header.setHeaderFlagAndVersion(param.getHeaderFlagAndVersion());
        request.header.setDestinationId(param.getDestinationId());
        request.header.setSourceId(param.getSourceId());
        request.header.setUserInfo(param.getUserInfo());
        request.messageType = param.getMessageType();
        request.body.putAll(param.getValueMap());
        request.header.initRequestHeader();
        return request;
    }

    public byte[] messageType2Bytes() {
        if (this.messageType == null || this.messageType.length() != 4
                || !CupsUtils.isNumberStr(this.messageType)) {
            throw new ComponentRuntimeException("报文类型标识4位数字");
        }
        return messageType.getBytes();
    }

    public byte[] header2Bytes() {
        return this.header.toBytes();
    }

    public TreeMap<String, ValueObject> getBody() {
        return body;
    }

    public String getMessageType() {
        return messageType;
    }

}
