package main

import (
	"fmt"
	"log"
	"time"

	"github.com/gorcon/rcon"
)

func (o *Orchestrator) tryRCONConnection(server GameServer) error {
	addr := fmt.Sprintf("localhost:%d", server.Port)

	conn, err := rcon.Dial(addr, server.RCONPassword,
		rcon.SetDialTimeout(3*time.Second),
		rcon.SetDeadline(5*time.Second),
	)
	if err != nil {
		return fmt.Errorf("RCON dial %s: %w", addr, err)
	}
	defer conn.Close()

	resp, err := conn.Execute("status")
	if err != nil {
		return fmt.Errorf("RCON execute status: %w", err)
	}

	if len(resp) == 0 {
		return fmt.Errorf("RCON empty response from %s", addr)
	}

	return nil
}

func (o *Orchestrator) loadMatchConfig(server GameServer) error {
	addr := fmt.Sprintf("localhost:%d", server.Port)

	conn, err := rcon.Dial(addr, server.RCONPassword,
		rcon.SetDialTimeout(5*time.Second),
		rcon.SetDeadline(10*time.Second),
	)
	if err != nil {
		return fmt.Errorf("RCON dial for config load: %w", err)
	}
	defer conn.Close()

	configURL := o.matchConfigURL(*server.MatchID)

	// matchzy_loadmatch_url accepts an optional header key/value pair, used here
	// to send the Bearer token the backend requires for internal endpoints.
	cmd := fmt.Sprintf(
		`matchzy_loadmatch_url "%s" "Authorization" "Bearer %s"`,
		configURL,
		o.config.APISecret,
	)

	log.Printf("[rcon] loading match config for %s from %s", *server.MatchID, configURL)

	resp, err := conn.Execute(cmd)
	if err != nil {
		return fmt.Errorf("RCON execute matchzy_loadmatch_url: %w", err)
	}

	log.Printf("[rcon] matchzy_loadmatch_url response: %s", resp)
	return nil
}

func (o *Orchestrator) matchConfigURL(matchID string) string {
	return fmt.Sprintf("%s/api/internal/match-config/%s", o.config.APIURL, matchID)
}

func (o *Orchestrator) sendRCONCommand(server GameServer, command string) (string, error) {
	addr := fmt.Sprintf("localhost:%d", server.Port)

	conn, err := rcon.Dial(addr, server.RCONPassword,
		rcon.SetDialTimeout(5*time.Second),
		rcon.SetDeadline(10*time.Second),
	)
	if err != nil {
		return "", fmt.Errorf("RCON dial: %w", err)
	}
	defer conn.Close()

	resp, err := conn.Execute(command)
	if err != nil {
		return "", fmt.Errorf("RCON execute %q: %w", command, err)
	}

	return resp, nil
}
