package main

import (
	"strings"
	"testing"

	"hamlog/internal/extsvc"
)

// An upload to a service with no credentials used to look exactly like one that
// worked: it ran on its own goroutine and reported into the QSL Manager's
// console, which is not open when the command came from the QSO list.
func TestUploadRefusesAnUnconfiguredService(t *testing.T) {
	var empty extsvc.ExternalServices
	for _, svc := range []extsvc.Service{
		extsvc.ServiceCloudlog, extsvc.ServiceQRZ, extsvc.ServiceClublog,
		extsvc.ServiceHRDLog, extsvc.ServiceEQSL, extsvc.ServiceHamQTH, extsvc.ServiceLoTW,
	} {
		err := uploadConfigured(svc, empty)
		if err == nil {
			t.Errorf("%s: an unconfigured service was accepted", svc)
			continue
		}
		if !strings.Contains(err.Error(), "Settings") {
			t.Errorf("%s: %q does not say where to fix it", svc, err)
		}
	}
}

// And a CONFIGURED service is not turned away. Club Log is the one that was:
// its API key is OpsLog's own application key, embedded and never entered, so
// demanding it refused every operator who had the service working.
func TestAConfiguredServiceIsAccepted(t *testing.T) {
	var cfg extsvc.ExternalServices
	cfg.Clublog.Email, cfg.Clublog.Password, cfg.Clublog.Callsign = "f4bpo@example.com", "secret", "F4BPO"
	cfg.QRZ.APIKey = "1234-5678"
	cfg.Cloudlog.URL, cfg.Cloudlog.APIKey, cfg.Cloudlog.StationID = "https://log.example.com", "cl-key", "3"
	cfg.EQSL.Username, cfg.EQSL.Password = "F4BPO", "secret"
	cfg.HamQTH.Username, cfg.HamQTH.Password = "f4bpo", "secret"
	cfg.HRDLog.Callsign, cfg.HRDLog.Code = "F4BPO", "12345"
	cfg.LoTW.TQSLPath, cfg.LoTW.StationLocation = `C:\Program Files (x86)\TrustedQSL\tqsl.exe`, "Home"

	for _, svc := range []extsvc.Service{
		extsvc.ServiceCloudlog, extsvc.ServiceQRZ, extsvc.ServiceClublog,
		extsvc.ServiceHRDLog, extsvc.ServiceEQSL, extsvc.ServiceHamQTH, extsvc.ServiceLoTW,
	} {
		if err := uploadConfigured(svc, cfg); err != nil {
			t.Errorf("%s: a configured service was refused: %v", svc, err)
		}
	}
}

// The message names what is actually missing, so the operator opens the right
// field rather than checking three that were already filled in.
func TestTheRefusalNamesTheMissingFields(t *testing.T) {
	var cfg extsvc.ExternalServices
	cfg.Clublog.Email = "f4bpo@example.com"
	err := uploadConfigured(extsvc.ServiceClublog, cfg)
	if err == nil {
		t.Fatal("a half-configured Club Log was accepted")
	}
	msg := err.Error()
	if strings.Contains(msg, "email") {
		t.Errorf("%q asks for the one field that IS set", msg)
	}
	for _, want := range []string{"password", "logbook callsign"} {
		if !strings.Contains(msg, want) {
			t.Errorf("%q does not mention the missing %s", msg, want)
		}
	}
	if strings.Contains(strings.ToLower(msg), "api key") {
		t.Errorf("%q asks for the API key — it is OpsLog's own, embedded", msg)
	}
}
