package pluginheart

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"log/slog"
	"net/http"
	"os"
	"strings"
	"time"
)

type Engine struct {
	api  string
	cli  *http.Client
	name string
}

func NewEngine(name, api string) *Engine {
	e := Engine{
		api:  api,
		name: name,
		cli: &http.Client{
			Timeout: 5 * time.Second,
		},
	}
	return &e
}

func (e *Engine) AutoHeart(in HeartInput, isService bool) {
	ticker := time.NewTicker(5 * time.Second)
	defer ticker.Stop()

	maxFaildCount := 3
	if isService {
		maxFaildCount = 17280
	}

	var faildCount int
	for {
		if faildCount > maxFaildCount {
			fmt.Println("heart failed")
			os.Exit(0)
		}

		resp, err := e.Heart(in)
		<-ticker.C

		if err != nil {
			slog.Error("heart failed", "error", err)
			e.api = strings.ReplaceAll(e.api, "127.0.0.1", "localhost")
			faildCount++
			continue
		}
		body, _ := io.ReadAll(resp.Body)
		resp.Body.Close()
		if resp.StatusCode != 200 {
			slog.Error("heart failed", "error", resp.StatusCode, "body", string(body))
			faildCount++
			continue
		}
		faildCount = 0
	}
}

func (e *Engine) Heart(in HeartInput) (*http.Response, error) {
	in.PID = os.Getpid()
	b, _ := json.Marshal(in)
	const path = `/extensions/heartbeat`

	req, _ := http.NewRequest(http.MethodPost, e.api+path, bytes.NewReader(b))
	SetExtensionName(req, e.name)
	return e.cli.Do(req)
}

func (e *Engine) Console(in ConsoleInput) (*http.Response, error) {
	b, _ := json.Marshal(in)
	const path = `/extensions/console`

	req, _ := http.NewRequest(http.MethodPost, e.api+path, bytes.NewReader(b))
	SetExtensionName(req, e.name)
	return e.cli.Do(req)
}

// GetExtensionName 获取扩展名称
func GetExtensionName(req *http.Request) string {
	return req.Header.Get("X-Extension-Name")
}

func SetExtensionName(req *http.Request, name string) {
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("X-Extension-Name", name)
}
