package api

import (
	"context"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"

	"github.com/stretchr/testify/require"
	"google.golang.org/protobuf/encoding/protojson"

	apipb "github.com/usememos/memos/proto/gen/api"
	"github.com/usememos/memos/server/auth"
)

// 放在固定提交的 server/api 包中运行，复用项目临时数据库和测试用户辅助函数。
// 令牌只在测试进程中生成，不连接已部署的 Memos 实例。
func TestBlogMemoRequestBinding(t *testing.T) {
	svc, ctx := newUploadTestService(t)
	user, err := svc.fetchCurrentUser(ctx)
	require.NoError(t, err)
	token, _, err := auth.GenerateAccessTokenV2(user.ID, user.Username, string(user.Role), string(user.RowStatus), user.PasswordHash, []byte(svc.Secret))
	require.NoError(t, err)
	handler, err := svc.NewHandler(context.Background())
	require.NoError(t, err)

	tests := []struct {
		name       string
		path       string
		body       string
		authed     bool
		wantStatus int
		wantName   string
	}{
		{"REST_body_is_memo", "/api/memos?memo_id=lesson-rest", `{"content":"binding probe","visibility":"PRIVATE"}`, true, 200, "memos/lesson-rest"},
		{"Connect_body_is_request", "/memos.api.MemoService/CreateMemo", `{"memo":{"content":"binding probe","visibility":"PRIVATE"},"memoId":"lesson-connect"}`, true, 200, "memos/lesson-connect"},
		{"REST_anonymous_is_rejected", "/api/memos", `{"content":"anonymous"}`, false, 401, ""},
		{"Connect_flat_body_is_rejected", "/memos.api.MemoService/CreateMemo", `{"content":"wrong shape"}`, true, 400, ""},
	}
	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			req := httptest.NewRequest(http.MethodPost, tc.path, strings.NewReader(tc.body))
			req.Header.Set("Content-Type", "application/json")
			req.Header.Set("Connect-Protocol-Version", "1")
			if tc.authed {
				req.Header.Set("Authorization", "Bearer "+token)
			}
			recorder := httptest.NewRecorder()
			handler.ServeHTTP(recorder, req)
			require.Equal(t, tc.wantStatus, recorder.Code, "响应状态与预期不符：%s", recorder.Body.String())
			if tc.wantName == "" {
				return
			}
			var memo apipb.Memo
			require.NoError(t, protojson.Unmarshal(recorder.Body.Bytes(), &memo))
			require.Equal(t, tc.wantName, memo.Name, "资源名不符")
			require.Equal(t, "binding probe", memo.Content, "正文未按约定绑定")
		})
	}
}
