/*
 * Copyright 2021 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package netpollmux

import (
	"encoding/binary"
	"testing"

	"github.com/cloudwego/gopkg/protocol/ttheader"
	"github.com/cloudwego/netpoll"

	"github.com/cloudwego/kitex/internal/test"
	"github.com/cloudwego/kitex/pkg/remote/codec"
)

func TestParseHeader(t *testing.T) {
	s := "hello world"
	seqID := int32(1)
	reader := mockHeader(seqID, s)

	l, id, err := parseHeader(reader)
	test.Assert(t, err == nil, err)
	test.Assert(t, id == seqID, id, seqID)

	rl := reader.Len()
	test.Assert(t, l == rl, l, rl)
}

// TestParseHeaderErr test parseHeader return err
func TestParseHeaderErr(t *testing.T) {
	s := "hello world"

	reader := netpoll.NewLinkBuffer()
	buf, _ := reader.Malloc(1 * codec.Size32)
	// length
	binary.BigEndian.PutUint32(buf[:codec.Size32], uint32(0))

	reader.WriteString(s)
	reader.Flush()

	_, _, err := parseHeader(reader)
	test.Assert(t, err != nil, err)

	reader = netpoll.NewLinkBuffer()
	buf, _ = reader.Malloc(1 * codec.Size32)
	// length
	binary.BigEndian.PutUint32(buf[:codec.Size32], uint32(1))
	// TTHeader
	binary.BigEndian.PutUint32(buf[:codec.Size32], uint32(1))

	reader.WriteString(s)
	reader.Flush()
	_, _, err = parseHeader(reader)
	test.Assert(t, err != nil, err)
}

// 0-4Byte length, 4-8Byte version check, 8-12Byte seqID
func mockHeader(seqID int32, body string) *netpoll.LinkBuffer {
	reader := netpoll.NewLinkBuffer()
	buf, _ := reader.Malloc(3 * codec.Size32)
	// length
	binary.BigEndian.PutUint32(buf[:codec.Size32], uint32(len(body))+(2*codec.Size32))
	// TTHeader
	binary.BigEndian.PutUint32(buf[codec.Size32:2*codec.Size32], ttheader.TTHeaderMagic)
	// seqID
	binary.BigEndian.PutUint32(buf[2*codec.Size32:3*codec.Size32], uint32(seqID))
	reader.WriteString(body)
	reader.Flush()
	return reader
}
