package runtime

import (
	"encoding/json"
	"fmt"
	"regexp"
	"strings"
)

const (
	maxWebSearchQueryBytes     = 512
	knowledgeWebSearchFunction = "knowledge_web_search"
	knowledgeWebReadFunction   = "knowledge_web_read"
)

type knowledgeWebSearchArguments struct {
	Query string `json:"query"`
}

type knowledgeWebReadArguments struct {
	WebRef string `json:"webRef"`
}

type explorationWebSearchResult struct {
	OK        bool                             `json:"ok"`
	Results   []explorationWebSearchResultItem `json:"results"`
	Truncated bool                             `json:"truncated"`
	Hint      string                           `json:"hint,omitempty"`
}

type explorationWebSearchResultItem struct {
	WebRef      string `json:"webRef"`
	Title       string `json:"title,omitempty"`
	URL         string `json:"url"`
	Snippet     string `json:"snippet,omitempty"`
	Source      string `json:"source,omitempty"`
	PublishedAt string `json:"publishedAt,omitempty"`
}

type explorationWebReadResult struct {
	OK        bool                        `json:"ok"`
	Evidence  *explorationWebReadEvidence `json:"evidence,omitempty"`
	Truncated bool                        `json:"truncated"`
}

type explorationWebReadEvidence struct {
	ID        string `json:"id"`
	WebRef    string `json:"webRef"`
	Title     string `json:"title,omitempty"`
	URL       string `json:"url"`
	Source    string `json:"source,omitempty"`
	FetchedAt string `json:"fetchedAt,omitempty"`
	Content   string `json:"content"`
}

func validateWebSearchArguments(fields map[string]json.RawMessage, arguments *knowledgeWebSearchArguments) error {
	if fieldMissingOrNull(fields, "query") {
		return fmt.Errorf("query is required")
	}
	arguments.Query = strings.TrimSpace(arguments.Query)
	if arguments.Query == "" || len(arguments.Query) > maxWebSearchQueryBytes {
		return fmt.Errorf("query is invalid")
	}
	if len(fields) != 1 {
		return fmt.Errorf("unsupported web search argument")
	}
	return nil
}

func validateWebReadArguments(fields map[string]json.RawMessage, arguments *knowledgeWebReadArguments) error {
	if fieldMissingOrNull(fields, "webRef") {
		return fmt.Errorf("webRef is required")
	}
	arguments.WebRef = strings.TrimSpace(arguments.WebRef)
	if len(arguments.WebRef) > maxReferenceBytes || !webReferencePattern.MatchString(arguments.WebRef) || len(fields) != 1 {
		return fmt.Errorf("webRef is invalid")
	}
	return nil
}

var webReferencePattern = regexp.MustCompile(`^w[1-9][0-9]*$`)
