package core

import (
	"fmt"
	"sync"

	"github.com/metacubex/mihomo/hub"
	"github.com/metacubex/mihomo/hub/executor"
)

type Engine struct {
	mu         sync.Mutex
	apiAddr    string
	secret     string
	lastGood   []byte
	running    bool
}

func NewEngine() *Engine {
	return &Engine{}
}

func (e *Engine) Configure(apiAddr, secret string) {
	e.mu.Lock()
	defer e.mu.Unlock()
	e.apiAddr = apiAddr
	e.secret = secret
}

func (e *Engine) Reload(yaml []byte) error {
	e.mu.Lock()
	defer e.mu.Unlock()

	if _, err := executor.ParseWithBytes(yaml); err != nil {
		return fmt.Errorf("config validation failed: %w", err)
	}

	opts := []hub.Option{
		hub.WithExternalController(e.apiAddr),
	}
	if e.secret != "" {
		opts = append(opts, hub.WithSecret(e.secret))
	}

	if err := hub.Parse(yaml, opts...); err != nil {
		return fmt.Errorf("mihomo reload failed: %w", err)
	}

	e.lastGood = append([]byte(nil), yaml...)
	e.running = true
	return nil
}

func (e *Engine) Shutdown() {
	e.mu.Lock()
	defer e.mu.Unlock()
	executor.Shutdown()
	e.running = false
}

func (e *Engine) LastGoodConfig() []byte {
	e.mu.Lock()
	defer e.mu.Unlock()
	if e.lastGood == nil {
		return nil
	}
	return append([]byte(nil), e.lastGood...)
}

func (e *Engine) Running() bool {
	e.mu.Lock()
	defer e.mu.Unlock()
	return e.running
}
