package yu_proto

import (
	yu_base64 "gogs.qqck.cn/s/tools/base64"
	yu_strconv "gogs.qqck.cn/s/tools/strconv"
	"strconv"
)

func (t *Protobuf) Json() string {
	t.tmp_buf = nil
	if t.list.id == 0 {
		return string(t.tmp_buf)
	}
	t.json_obj(t.list)
	return string(t.tmp_buf)
}

func (t *Protobuf) json_obj(list *node) {
	t.tmp_buf = append(t.tmp_buf, '{')
	j_end := false
	for {
		if list.id != 0 {
			j_end = true
			t.tmp_buf = append(t.tmp_buf, '"')
			t.tmp_buf = append(t.tmp_buf, yu_strconv.FormatUint64(list.id)...)
			t.tmp_buf = append(t.tmp_buf, '"', ':')
			t.json_value(list.value)
			t.tmp_buf = append(t.tmp_buf, ',')
		}
		if list._next == nil {
			break
		}
		list = list._next
	}
	if j_end {
		t.tmp_buf[len(t.tmp_buf)-1] = '}'
	} else {
		t.tmp_buf = append(t.tmp_buf, '}')
	}
}

func (t *Protobuf) json_arr(list *[]*node) {
	t.tmp_buf = append(t.tmp_buf, '[')
	j_end := false
	for _, j_value := range *list {
		j_end = true
		t.json_value(j_value)
		t.tmp_buf = append(t.tmp_buf, ',')
	}
	if j_end {
		t.tmp_buf[len(t.tmp_buf)-1] = ']'
	} else {
		t.tmp_buf = append(t.tmp_buf, ']')
	}
}

func (t *Protobuf) json_value(value any) {
	switch j_value := value.(type) {
	case bool:
		if j_value {
			t.tmp_buf = append(t.tmp_buf, 't', 'r', 'u', 'e')
		} else {
			t.tmp_buf = append(t.tmp_buf, 'f', 'a', 'l', 's', 'e')
		}
	case byte:
		t.tmp_buf = append(t.tmp_buf, yu_strconv.FormatByte(j_value)...)
	case int8:
		t.tmp_buf = append(t.tmp_buf, yu_strconv.FormatInt8(j_value)...)
	case int16:
		t.tmp_buf = append(t.tmp_buf, yu_strconv.FormatInt16(j_value)...)
	case uint16:
		t.tmp_buf = append(t.tmp_buf, yu_strconv.FormatUint16(j_value)...)
	case int32:
		t.tmp_buf = append(t.tmp_buf, yu_strconv.FormatInt32(j_value)...)
	case uint32:
		t.tmp_buf = append(t.tmp_buf, yu_strconv.FormatUint32(j_value)...)
	case int64:
		t.tmp_buf = append(t.tmp_buf, yu_strconv.FormatInt64(j_value)...)
	case uint64:
		t.tmp_buf = append(t.tmp_buf, yu_strconv.FormatUint64(j_value)...)
	case float32:
		t.tmp_buf = append(t.tmp_buf, strconv.FormatFloat(float64(j_value), 'f', -1, 32)...)
	case float64:
		t.tmp_buf = append(t.tmp_buf, strconv.FormatFloat(j_value, 'f', -1, 64)...)
	case []byte:
		t.tmp_buf = append(t.tmp_buf, '"')
		t.tmp_buf = append(t.tmp_buf, yu_base64.Std.Encode2S(j_value)...)
		t.tmp_buf = append(t.tmp_buf, '"')
	case *node:
		if j_value == nil {
			t.tmp_buf = append(t.tmp_buf, 'n', 'u', 'l', 'l')
			return
		} else if j_value.id == 0 {
			// 如果 id 等于 0 则是数组成员
			t.json_value(j_value.value)
		} else {
			t.json_obj(j_value)
		}
	case *[]*node:
		t.json_arr(j_value)
	default:
		panic("不支持的数据类型")
	}
}
