// Code generated by Makefile, DO NOT EDIT.

/*
 * Copyright 2023 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 avx

import (
	"os"
	"runtime"
	"runtime/debug"
	"testing"
	"time"
	"unsafe"

	"github.com/bytedance/sonic/loader"
	"github.com/cloudwego/dynamicgo/internal/caching"
	"github.com/cloudwego/dynamicgo/internal/types"
	"github.com/stretchr/testify/assert"
)

var (
	debugAsyncGC = os.Getenv("SONIC_NO_ASYNC_GC") == ""
)

var stubs = []loader.GoC{
	{"_tb_write_i64", nil, &__tb_write_i64},
	{"_hm_get", nil, &__hm_get},
	{"_trie_get", nil, &__trie_get},
	{"_j2t_fsm_exec", nil, &__j2t_fsm_exec},
	{"_tb_skip", nil, &__tb_skip},
	{"_f64toa", nil, &__f64toa},
	{"_i64toa", nil, &__i64toa},
    {"_quote", nil, &__quote},
}

func TestMain(m *testing.M) {
	loader.WrapGoC(Text__native_entry__, Funcs, stubs, "avx", "avx/native.c")

	go func() {
		if !debugAsyncGC {
			return
		}
		println("Begin GC looping...")
		for {
			runtime.GC()
			debug.FreeOSMemory()
		}
		println("stop GC looping!")
	}()
	time.Sleep(time.Millisecond * 100)
	m.Run()
}

func TestNative_tb_write_i64(t *testing.T) {
	v := int64(0x0102030405060708)
	buf := make([]byte, 0, 4)
	ret := tb_write_i64(&buf, v)
	assert.Equal(t, uint64(4<<types.ERR_WRAP_SHIFT_CODE)|uint64(types.ERR_OOM_BUF), ret)
	assert.Equal(t, 0, len(buf))
	buf = make([]byte, 0, 9)
	ret = tb_write_i64(&buf, v)
	assert.Equal(t, []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, buf)
}

func TestNative_hm_get(t *testing.T) {
	var hm = caching.NewHashMap(10, 4)
	var v = int(0)
	var p = unsafe.Pointer(&v)
	var ex = "exist"
	var ne = "not-exist"
	hm.Set(ex, p)
	if ret := hm_get(hm, &ex); ret != p {
		t.Fatal(ret)
	}
	if ret := hm_get(hm, &ne); ret != nil {
		t.Fatal(ret)
	}
}

func TestNative_trie_get(t *testing.T) {
	var tt = &caching.TrieTree{}
	var v = int(0)
	var p = unsafe.Pointer(&v)
	var ex = "exist"
	var ne = "not-exist"
	tt.Set(ex, p)
	if ret := trie_get(tt, &ex); ret != p {
		t.Fatal(ret)
	}
	if ret := trie_get(tt, &ne); ret != nil {
		t.Fatal(ret)
	}
}

func TestRecover_j2t_fsm_exec(t *testing.T) {
    // var fsm = types.NewJ2TStateMachine()
	var js = `{}`
	var buf = make([]byte,0, 256)
	type args struct {
		fsm  *types.J2TStateMachine
		buf  *[]byte
		src  *string
		flag uint64
	}
	tests := []struct {
		name    string
		args    args
		wantRet uint64
	}{
		{"1", args{nil, &buf, &js, 0}, 0},
		// {"2", args{fsm, nil, &js, 0}, 0},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
            defer func() {
                if r := recover(); r != nil {
                    t.Log("recover: ", r)
                } else {
                    t.Fatal("no panic")
                }
            }()
            _ = j2t_fsm_exec(tt.args.fsm, tt.args.buf, tt.args.src, tt.args.flag)
		})
	}
}

func TestRecover_tb_skip(t *testing.T) {
    // var fsm = types.NewTStateMachine()
	var buf = make([]byte, 256)
	type args struct {
		fsm  *types.TStateMachine
		buf  *byte
		n int
        t uint8
	}
	tests := []struct {
		name    string
		args    args
		wantRet uint64
	}{
		{"1", args{nil, &buf[0], 10, 2}, 0},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
            defer func() {
                if r := recover(); r != nil {
                    t.Log("recover: ", r)
                } else {
                    t.Fatal("no panic")
                }
            }()
            _ = tb_skip(tt.args.fsm, tt.args.buf, tt.args.n, tt.args.t)
		})
	}
}
