package miner

import (
	"strings"
	"testing"

	"crypto-miner-agent/config"
)

func TestNewStratumClient(t *testing.T) {
	pool := NewPool(1, testPoolCfg(), nil, nil)
	sc := NewStratumClient(pool, config.RuntimeConfig{})
	if sc == nil || sc.pool != pool {
		t.Fatal("NewStratumClient should wire pool")
	}
}

func TestStratumSetJobSkipsInvalid(t *testing.T) {
	pool := NewPool(1, testPoolCfg(), nil, nil)
	sc := NewStratumClient(pool, config.RuntimeConfig{})

	sc.setJob(nil)
	sc.setJob(&stratumJob{Blob: ""})
	pool.mu.RLock()
	if pool.currentJob != nil {
		pool.mu.RUnlock()
		t.Fatal("nil/empty stratum job should not set pool job")
	}
	pool.mu.RUnlock()

	sc.setJob(&stratumJob{
		Blob: strings.Repeat("aa", 76), JobID: "42", Target: "ffff", SeedHash: strings.Repeat("bb", 32), Height: 10,
	})
	pool.mu.RLock()
	defer pool.mu.RUnlock()
	if pool.currentJob == nil {
		t.Fatal("valid stratum job should set pool job")
	}
	wantBlob := strings.Repeat("aa", 76)
	if pool.currentJob.ID != "42" || pool.currentJob.Blob != wantBlob {
		t.Fatalf("pool job mismatch: %+v", pool.currentJob)
	}
	wantSeed := strings.Repeat("bb", 32)
	if pool.currentJob.Target != "ffff" || pool.currentJob.SeedHash != wantSeed {
		t.Fatalf("pool job fields: %+v", pool.currentJob)
	}
}

func TestStratumRunFallbackNoPoolHost(t *testing.T) {
	pool := NewPool(1, testPoolCfg(), nil, nil)
	sc := NewStratumClient(pool, config.RuntimeConfig{})
	stop := make(chan struct{})
	close(stop)
	// Should return immediately without dialing.
	sc.RunFallback(stop)
}

func TestStratumSetJobMapsToInternalJob(t *testing.T) {
	pool := NewPool(1, testPoolCfg(), nil, nil)
	sc := NewStratumClient(pool, config.RuntimeConfig{})
	sc.setJob(&stratumJob{
		Blob: strings.Repeat("cc", 76), JobID: "jid", Target: "tgt", SeedHash: strings.Repeat("dd", 32),
	})
	pool.mu.RLock()
	j := pool.currentJob
	pool.mu.RUnlock()
	if j == nil || j.ID != "jid" || j.Blob != strings.Repeat("cc", 76) {
		t.Fatalf("expected internal job, got %+v", j)
	}
}
