package internal

import (
	"encoding/base64"
	"net/http"
	"os"
	"testing"

	"github.com/fullstorydev/grpcurl"
	"github.com/stretchr/testify/assert"
	"github.com/zeromicro/go-zero/core/hash"
)

const (
	b64pb                = `CpgBCgtoZWxsby5wcm90bxIFaGVsbG8iHQoHUmVxdWVzdBISCgRwaW5nGAEgASgJUgRwaW5nIh4KCFJlc3BvbnNlEhIKBHBvbmcYASABKAlSBHBvbmcyMAoFSGVsbG8SJwoEUGluZxIOLmhlbGxvLlJlcXVlc3QaDy5oZWxsby5SZXNwb25zZUIJWgcuL2hlbGxvYgZwcm90bzM=`
	b64pbWithAnnotations = `[encoded data, 11948 characters]`
)

func TestGetMethods(t *testing.T) {
	tmpfile, err := os.CreateTemp(os.TempDir(), hash.Md5Hex([]byte(b64pb)))
	assert.Nil(t, err)
	b, err := base64.StdEncoding.DecodeString(b64pb)
	assert.Nil(t, err)
	assert.Nil(t, os.WriteFile(tmpfile.Name(), b, os.ModeTemporary))
	defer os.Remove(tmpfile.Name())

	source, err := grpcurl.DescriptorSourceFromProtoSets(tmpfile.Name())
	assert.Nil(t, err)
	methods, err := GetMethods(source)
	assert.Nil(t, err)
	assert.EqualValues(t, []Method{
		{
			RpcPath: "hello.Hello/Ping",
		},
	}, methods)
}

func TestGetMethodsWithAnnotations(t *testing.T) {
	tmpfile, err := os.CreateTemp(os.TempDir(), hash.Md5Hex([]byte(b64pb)))
	assert.Nil(t, err)
	b, err := base64.StdEncoding.DecodeString(b64pbWithAnnotations)
	assert.Nil(t, err)
	assert.Nil(t, os.WriteFile(tmpfile.Name(), b, os.ModeTemporary))
	defer os.Remove(tmpfile.Name())

	source, err := grpcurl.DescriptorSourceFromProtoSets(tmpfile.Name())
	assert.Nil(t, err)
	methods, err := GetMethods(source)
	assert.Nil(t, err)
	assert.EqualValues(t, []Method{
		{
			HttpMethod: http.MethodGet,
			HttpPath:   "/v1/get/:foo",
			RpcPath:    "hello.Hello/PingGet",
		},
		{
			HttpMethod: http.MethodPost,
			HttpPath:   "/v1/post",
			RpcPath:    "hello.Hello/PingPost",
		},
		{
			HttpMethod: http.MethodPut,
			HttpPath:   "/v1/put",
			RpcPath:    "hello.Hello/PingPut",
		},
		{
			HttpMethod: http.MethodDelete,
			HttpPath:   "/v1/delete",
			RpcPath:    "hello.Hello/PingDelete",
		},
		{
			HttpMethod: http.MethodPatch,
			HttpPath:   "/v1/patch",
			RpcPath:    "hello.Hello/PingPatch",
		},
	}, methods)
}
