package chatapi_test

import (
	"fmt"
	"net/http"

	"github.com/ardanlabs/kronk/cmd/server/app/sdk/apitest"
	"github.com/ardanlabs/kronk/cmd/server/app/sdk/errs"
	"github.com/ardanlabs/kronk/sdk/kronk/model"
	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
)

func chatEmbed200(tokens map[string]string) []apitest.Table {
	table := []apitest.Table{
		{
			Name:       "good-token",
			URL:        "/v1/embeddings",
			Token:      tokens["embeddings"],
			Method:     http.MethodPost,
			StatusCode: http.StatusOK,
			Input: model.D{
				"model":       "embeddinggemma-300m-qat-Q8_0",
				"input":       "Embed this sentence",
				"max_tokens":  2048,
				"temperature": 0.7,
				"top_p":       0.9,
				"top_k":       40,
			},
			GotResp: &model.EmbedReponse{},
			ExpResp: &model.EmbedReponse{
				Model:  "embeddinggemma-300m-qat-Q8_0",
				Object: "list",
				Data: []model.EmbedData{
					{
						Object: "embedding",
						Index:  0,
					},
				},
				Usage: model.EmbedUsage{
					PromptTokens: 5,
					TotalTokens:  5,
				},
			},
			CmpFunc: func(got any, exp any) string {
				diff := cmp.Diff(got, exp,
					cmpopts.IgnoreFields(model.EmbedReponse{}, "Data", "Created"),
					cmpopts.IgnoreFields(model.EmbedData{}, "Embedding"),
				)

				if diff != "" {
					return diff
				}

				expResp, ok := got.(*model.EmbedReponse)
				if !ok {
					return fmt.Sprintf("response wrong type: %T", got)
				}

				if len(expResp.Data) != 1 {
					return fmt.Sprintf("expected length of 1, got %d", len(expResp.Data))
				}

				if len(expResp.Data[0].Embedding) != 768 {
					return "expecting a vector of 768 dimensions"
				}

				return ""
			},
		},
		{
			Name:       "multi-good-token",
			URL:        "/v1/embeddings",
			Token:      tokens["embeddings"],
			Method:     http.MethodPost,
			StatusCode: http.StatusOK,
			Input: model.D{
				"model":       "embeddinggemma-300m-qat-Q8_0",
				"input":       []string{"Embed this sentence", "and this sentence"},
				"max_tokens":  2048,
				"temperature": 0.7,
				"top_p":       0.9,
				"top_k":       40,
			},
			GotResp: &model.EmbedReponse{},
			ExpResp: &model.EmbedReponse{
				Model:  "embeddinggemma-300m-qat-Q8_0",
				Object: "list",
				Data: []model.EmbedData{
					{
						Object: "embedding",
						Index:  0,
					},
				},
				Usage: model.EmbedUsage{
					PromptTokens: 10,
					TotalTokens:  10,
				},
			},
			CmpFunc: func(got any, exp any) string {
				diff := cmp.Diff(got, exp,
					cmpopts.IgnoreFields(model.EmbedReponse{}, "Data", "Created"),
					cmpopts.IgnoreFields(model.EmbedData{}, "Embedding"),
				)

				if diff != "" {
					return diff
				}

				expResp, ok := got.(*model.EmbedReponse)
				if !ok {
					return fmt.Sprintf("response wrong type: %T", got)
				}

				if len(expResp.Data) != 2 {
					return fmt.Sprintf("expected length of 2, got %d", len(expResp.Data))
				}

				if len(expResp.Data[0].Embedding) != 768 {
					return "expecting a vector of 768 dimensions"
				}

				if len(expResp.Data[1].Embedding) != 768 {
					return "expecting a vector of 768 dimensions"
				}

				return ""
			},
		},
	}

	return table
}

func embed401(tokens map[string]string) []apitest.Table {
	table := []apitest.Table{
		{
			Name:       "bad-token",
			URL:        "/v1/embeddings",
			Token:      tokens["chat-completions"],
			Method:     http.MethodPost,
			StatusCode: http.StatusUnauthorized,
			Input: model.D{
				"model":       "embeddinggemma-300m-qat-Q8_0",
				"input":       "Embed this sentence",
				"max_tokens":  2048,
				"temperature": 0.7,
				"top_p":       0.9,
				"top_k":       40,
			},
			GotResp: &errs.Error{},
			ExpResp: &errs.Error{
				Code:    errs.Unauthenticated,
				Message: "rpc error: code = Unauthenticated desc = not authorized: attempted action is not allowed: endpoint \"embeddings\" not authorized",
			},
			CmpFunc: func(got any, exp any) string {
				diff := cmp.Diff(got, exp,
					cmpopts.IgnoreFields(errs.Error{}, "FuncName", "FileName"),
				)

				if diff != "" {
					return diff
				}

				return ""
			},
		},
		{
			Name:       "admin-only-token",
			URL:        "/v1/embeddings",
			Token:      tokens["admin"],
			Method:     http.MethodPost,
			StatusCode: http.StatusUnauthorized,
			Input: model.D{
				"model":       "embeddinggemma-300m-qat-Q8_0",
				"input":       "Embed this sentence",
				"max_tokens":  2048,
				"temperature": 0.7,
				"top_p":       0.9,
				"top_k":       40,
			},
			GotResp: &errs.Error{},
			ExpResp: &errs.Error{
				Code:    errs.Unauthenticated,
				Message: "rpc error: code = Unauthenticated desc = not authorized: attempted action is not allowed: endpoint \"embeddings\" not authorized",
			},
			CmpFunc: func(got any, exp any) string {
				diff := cmp.Diff(got, exp,
					cmpopts.IgnoreFields(errs.Error{}, "FuncName", "FileName"),
				)

				if diff != "" {
					return diff
				}

				return ""
			},
		},
	}

	return table
}
