package httpapi

import (
	"encoding/json"
	"io"
	"net/http"

	"github.com/easyai/easyai-ai-gateway/apps/api/internal/clients"
	"github.com/easyai/easyai-ai-gateway/apps/api/internal/runner"
)

const maxInternalExecutionRequestBytes = 64 * 1024

func (s *Server) internalExecution(w http.ResponseWriter, r *http.Request) {
	body := http.MaxBytesReader(w, r.Body, maxInternalExecutionRequestBytes)
	defer body.Close()
	var input runner.InternalExecutionRequest
	decoder := json.NewDecoder(body)
	decoder.DisallowUnknownFields()
	if err := decoder.Decode(&input); err != nil {
		http.Error(w, "invalid internal execution request", http.StatusBadRequest)
		return
	}
	var trailing any
	if err := decoder.Decode(&trailing); err != io.EOF {
		http.Error(w, "invalid internal execution request", http.StatusBadRequest)
		return
	}
	w.Header().Set("Content-Type", "application/x-ndjson")
	w.Header().Set("Cache-Control", "no-store")
	encoder := json.NewEncoder(w)
	flusher, _ := w.(http.Flusher)
	writeFrame := func(frame runner.InternalExecutionFrame) error {
		if err := encoder.Encode(frame); err != nil {
			return err
		}
		if flusher != nil {
			flusher.Flush()
		}
		return nil
	}
	result, err := s.runner.ExecuteInternal(r.Context(), r.Header.Get("Authorization"), input, func(delta clients.StreamDeltaEvent) error {
		return writeFrame(runner.InternalExecutionFrame{Type: "delta", Delta: &delta})
	})
	if err != nil {
		_ = writeFrame(runner.InternalExecutionFrameForError(err))
		return
	}
	_ = writeFrame(runner.InternalExecutionFrame{Type: "result", Output: result.Output, Wire: result.Wire})
}
