package network

import (
	"bytes"
)

const (
	hexTable  = "0123456789abcdefABCDEF"
	hexPrefix = "0x"
)

type Byte byte

func (b Byte) Hex() string {
	dst := make([]byte, 2)
	dst[0] = hexTable[b>>4]
	dst[1] = hexTable[b&0x0f]
	return string(dst)
}

func (b Byte) String() string {
	return b.Hex()
}

type Bytes []byte

// Prepend 将 p 添加到 Bytes 前面
func (b Bytes) Prepend(p ...byte) Bytes {
	return append(p, b...)
}

// Append 将 p 添加到 Bytes 后面
func (b Bytes) Append(p ...byte) Bytes {
	return append(b, p...)
}

// AppendStr 将 s 转换成 []byte 后添加到 Bytes 后面
func (b Bytes) AppendStr(s string) Bytes {
	return append(b, []byte(s)...)
}

// From 从 Bytes 返回第 i 个字节
func (b Bytes) From(i int) Byte {
	return Byte(b[i])
}

// Trim 循环 p 并将其从 Bytes 中移除
func (b Bytes) Trim(p ...[]byte) Bytes {
	np := b
	for _, x := range p {
		bytes.ReplaceAll(b, x, nil)
	}
	return np
}

// TrimStr 循环 s 并将其转换为 []byte 后从 Bytes 中移除
func (b Bytes) TrimStr(s ...string) Bytes {
	ns := b
	for _, x := range s {
		ns = bytes.ReplaceAll(b, []byte(x), nil)
	}
	return ns
}

// TrimNUL 移除 b 字符串内的 NUL 符号
// 参考 https://stackoverflow.com/questions/54285346/remove-null-character-from-string
func (b Bytes) TrimNUL() Bytes {
	return bytes.ReplaceAll(b, []byte{'\x00'}, nil)
}

// TrimEnter 移除 b 字符串内的回车符号
func (b Bytes) TrimEnter() Bytes {
	return bytes.ReplaceAll(b, []byte{'\r'}, nil)
}

// Remake 将 b 重新分配并返回新的变量
func (b Bytes) Remake() Bytes {
	if len(b) == 0 {
		return []byte{}
	}
	n := make([]byte, len(b))
	for i := 0; i < len(b); i++ {
		n[i] = b[i]
	}
	return n
}

// Equal 与 dst 进行比较
func (b Bytes) Equal(dst Bytes) bool {
	if len(b) != len(dst) {
		return false
	}
	return bytes.Equal(b.Remake(), dst.Remake())
}

// CRC16 使用 Bytes 创建用于 Modbus/TCP 协议 2 个字节的 CRC 校验码(CRC16)
// 具体应用时需要使用 BigEndian (大端模式) 或 LittleEndian 转换
func (b Bytes) CRC16() uint16 {
	var crc uint16 = 0xFFFF
	for _, n := range b {
		crc ^= uint16(n)
		for i := 0; i < 8; i++ {
			if crc&1 != 0 {
				crc >>= 1
				crc ^= 0xA001
			} else {
				crc >>= 1
			}
		}
	}
	return crc
}

// Hex 返回不包含空格的 hex
func (b Bytes) Hex() string {
	if len(b) <= 0 {
		return ""
	}
	dst := make([]byte, len(b)*2)
	for i, v := range b {
		dst[i*3] = hexTable[v>>4]
		dst[i*3+1] = hexTable[v&0x0f]
	}
	dst = dst[:len(dst)-1]
	return string(dst)
}

// HexTo 返回包含空格的 hex
func (b Bytes) HexTo() string {
	if len(b) <= 0 {
		return ""
	}
	dst := make([]byte, len(b)*3)
	for i, v := range b {
		dst[i*3] = hexTable[v>>4]
		dst[i*3+1] = hexTable[v&0x0f]
		dst[i*3+2] = 32 // 补充空格
	}
	dst = dst[:len(dst)-1]
	return string(dst)
}

func (b Bytes) String() string {
	return b.HexTo()
}

func (b Bytes) ToString() String {
	return String(b)
}
