package adif_test

import (
	"context"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"hamlog/internal/adif"
	"hamlog/internal/db"
	"hamlog/internal/qso"
)

// End to end: an operator's own record, through a real SQLite logbook and back.
//
// Written because CONTEST_ID was reported as "not imported". It is imported, and
// this pins the whole path — parse, remap, insert, read back — rather than the
// conversion step alone, which was already green while the report stood. A field
// can be lost at five places between the file and the grid; only the round trip
// says which.
func TestContestIDSurvivesImport(t *testing.T) {
	dir := t.TempDir()
	conn, err := db.Open(filepath.Join(dir, "logbook.db"))
	if err != nil {
		t.Fatalf("open: %v", err)
	}
	defer conn.Close()

	const file = "<CALL:6>2E0CVN <QSO_DATE:8>20260725 <TIME_ON:6>120039 <STATE:5>EU005 <BAND:3>20M <FREQ:6>14.014 <MODE:2>CW <CONTEST_ID:9>RSGB-IOTA <RST_RCVD:3>599 <RST_SENT:3>599 <SRX_STRING:8>001EU005 <EOR>\n"
	path := filepath.Join(dir, "in.adi")
	if err := os.WriteFile(path, []byte(file), 0o644); err != nil {
		t.Fatal(err)
	}

	repo := qso.NewRepo(conn)
	im := &adif.Importer{Repo: repo, FieldMap: map[string]string{"state": "iota"}}
	res, err := im.ImportFile(context.Background(), path)
	if err != nil {
		t.Fatalf("import: %v", err)
	}
	t.Logf("result: %+v", res)

	rows, err := conn.Query("SELECT callsign, contest_id, iota, state FROM qso")
	if err != nil {
		t.Fatal(err)
	}
	defer rows.Close()
	n := 0
	for rows.Next() {
		var call, contest, iota, state any
		if err := rows.Scan(&call, &contest, &iota, &state); err != nil {
			t.Fatal(err)
		}
		n++
		t.Logf("stored: call=%v contest_id=%v iota=%v state=%v", call, contest, iota, state)
		if s := strings.TrimSpace(toS(contest)); s != "RSGB-IOTA" {
			t.Errorf("contest_id in the DATABASE = %q, want RSGB-IOTA", s)
		}
	}
	if n == 0 {
		t.Fatal("nothing was stored")
	}
}

func toS(v any) string {
	switch x := v.(type) {
	case string:
		return x
	case []byte:
		return string(x)
	}
	return ""
}
