package api

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestParsePort(t *testing.T) {
	tests := []struct {
		in   string
		want int
	}{
		{"8989", 8989},
		{"80", 80},
		{"abc", 8989},
		{"", 8989},
		{"0", 8989},
	}
	for _, tc := range tests {
		if got := parsePort(tc.in); got != tc.want {
			t.Fatalf("parsePort(%q) = %d, want %d", tc.in, got, tc.want)
		}
	}
}

func TestIsLoopbackHost(t *testing.T) {
	if !isLoopbackHost("localhost") {
		t.Fatal("localhost should be loopback")
	}
	if !isLoopbackHost("127.0.0.1") {
		t.Fatal("127.0.0.1 should be loopback")
	}
	if isLoopbackHost("192.168.1.1") {
		t.Fatal("192.168.1.1 should not be loopback")
	}
}

func TestItoa(t *testing.T) {
	if itoa(8989) != "8989" {
		t.Fatalf("itoa(8989) = %q", itoa(8989))
	}
	if itoa(0) != "0" {
		t.Fatalf("itoa(0) = %q", itoa(0))
	}
}

func TestGetServerInfoJSON(t *testing.T) {
	req := httptest.NewRequest(http.MethodGet, "/api/v1/server/info", nil)
	req.Host = "localhost:8989"
	rec := httptest.NewRecorder()
	GetServerInfo(rec, req, "")

	if rec.Code != http.StatusOK {
		t.Fatalf("status %d body %s", rec.Code, rec.Body.String())
	}
	var info ServerInfo
	if err := json.Unmarshal(rec.Body.Bytes(), &info); err != nil {
		t.Fatal(err)
	}
	if info.Port != 8989 {
		t.Fatalf("port = %d, want 8989", info.Port)
	}
	if info.WebSocketURL == "" || info.SuggestedURL == "" {
		t.Fatalf("missing URLs: %+v", info)
	}
}

func TestGetServerInfoPublicURLOverride(t *testing.T) {
	req := httptest.NewRequest(http.MethodGet, "/api/v1/server/info", nil)
	req.Host = "localhost:8989"
	rec := httptest.NewRecorder()
	GetServerInfo(rec, req, "https://forge.example.com:443")

	var info ServerInfo
	if err := json.Unmarshal(rec.Body.Bytes(), &info); err != nil {
		t.Fatal(err)
	}
	if info.SuggestedURL != "https://forge.example.com:443" {
		t.Fatalf("override not applied: %q", info.SuggestedURL)
	}
	if info.WebSocketURL != "wss://forge.example.com:443/ws/agent" {
		t.Fatalf("ws url = %q", info.WebSocketURL)
	}
}
