package com.nokia.sms.message;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

import com.nokia.sms.entity.BindRespStatus;
import com.nokia.sms.entity.CommandId;
import com.nokia.sms.exception.ParseException;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ServerMessageUtil {
    private static final String systemId = "smsTousu";
    private static final String password = "123456";
    private static final DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");

    /*
     * SMIT_BIND_RESP 0x80000001 绑定应答
     */
    public static byte[] getSmitBindRespMessage(BindRespStatus status) {
        // 初始化header
        MessageHeader header = new MessageHeader();
        // header 12 + body 1 所以是13字节
        header.setMessageLength(13);
        header.setCommandId(CommandId.SMIT_BIND_RESP);
        // 所有的初始连接需要从0开始
        header.setSequenceNumber(0L);
        // 初始化
        byte[] message = new byte[header.getMessageLength()];
        // 填充header
        System.arraycopy(header.toByteArray(), 0, message, 0, 12);

        // 填充status
        message[12] = status.value;
        return message;
    }

    /*
     * SMIT_ACTIVE_TEST_RESP 0x8000000f 链路检测应答
     */
    public static byte[] getSmitActiveTestRespMessage(long sequenceNumber) {
        // 初始化header
        MessageHeader header = new MessageHeader();
        // header 12 + body 0 所以是12字节
        header.setMessageLength(12);
        header.setCommandId(CommandId.SMIT_ACTIVE_TEST_RESP);
        // 从客户端获取下一个序号
        header.setSequenceNumber(sequenceNumber);
        // 初始化
        byte[] message = new byte[header.getMessageLength()];
        // 填充header
        System.arraycopy(header.toByteArray(), 0, message, 0, 12);
        return message;
    }

    /*
     * SMIT_DELBLK_RESP 0x80000003 解除黑名单应答
     */
    public static byte[] getSmitDelBlkRespMessage(long sequenceNumber) {
        // 初始化header
        MessageHeader header = new MessageHeader();
        // header 12 + body 0 所以是12字节
        header.setMessageLength(13);
        header.setCommandId(CommandId.SMIT_DELBLK_RESP);
        // 从客户端获取下一个序号
        header.setSequenceNumber(sequenceNumber);
        // 初始化
        byte[] message = new byte[header.getMessageLength()];
        // 填充header
        System.arraycopy(header.toByteArray(), 0, message, 0, 12);
        // 填充header
        message[12] = 0;
        return message;
    }

    /*
     * 服务端解析
     */
    public static byte[] parse(byte[] message) {
        try {
            MessageHeader header = MessageHeader.parse(message);
            log.debug("消息被服务端解析为 {} 消息, 序列号 {}", header.getCommandId(), header.getSequenceNumber());
            // 判断消息类型
            switch (header.getCommandId()) {
                case SMIT_ACTIVE_TEST:
                    // 链路检测消息返回 sequenceNumber
                    return getSmitActiveTestRespMessage(header.getSequenceNumber());
                case SMIT_DELBLK:
                    // 解除黑名单消息 返回成功
                    return getSmitDelBlkRespMessage(header.getSequenceNumber());
                case SMIT_BIND:
                    // 绑定请求消息 返回成功
                    return getSmitBindRespMessage(parseSmitBindMessage(message));
                default:
                    throw new ParseException("消息Command_Id错误");
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /*
     * SMIT_BIND 0x00000001 绑定请求
     */
    public static BindRespStatus parseSmitBindMessage(byte[] message) {
        try {
            MessageHeader header = MessageHeader.parse(message);
            // 判断消息类型
            if (CommandId.SMIT_BIND.equals(header.getCommandId())) {
                // 获取并对比systemId
                byte[] systemIdByteArray = Arrays.copyOfRange(message, 12, 28);
                if (systemId.equals(new String(systemIdByteArray).trim())) {
                    // 获取和判断鉴权信息
                    String authCodeString = password + dateFormat.format(new Date());
                    MessageDigest digest = MessageDigest.getInstance("SHA-1");
                    // sha1后的本地字符串
                    String authCodeLocal = new String(digest.digest(authCodeString.getBytes()));
                    // 获取到的authCode
                    String authCode = new String(Arrays.copyOfRange(message, 28, 48));
                    if (authCodeLocal.equals(authCode)) {
                        return BindRespStatus.SUCCESS;
                    }
                }
                return BindRespStatus.AUTH_ERROR;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return BindRespStatus.STRUCTURE_ERROR;
    }
}
