package ocr

import (
	"context"
	"os"
	"strings"
	"testing"
	"time"
)

// With CHIRAMI_FAKE_OCR set the test binary acts as a helper that replies
// with the request's length, so the client's framing is tested end to end.
func TestMain(m *testing.M) {
	if os.Getenv("CHIRAMI_FAKE_OCR") != "" {
		for {
			req, err := ReadRequest(os.Stdin)
			if err != nil {
				os.Exit(0)
			}
			WriteResult(os.Stdout, Result{Lines: []Line{{Text: strings.Repeat("あ", len(req))}, {Text: " い "}}})
		}
	}
	os.Exit(m.Run())
}

func fake(t *testing.T, idle time.Duration) *Client {
	exe, err := os.Executable()
	if err != nil {
		t.Fatal(err)
	}
	t.Setenv("CHIRAMI_FAKE_OCR", "1")
	c := &Client{Path: exe, Idle: idle}
	t.Cleanup(c.Close)
	return c
}

func TestClientRoundTrip(t *testing.T) {
	c := fake(t, 0)
	for _, n := range []int{3, 0, 5} {
		r, err := c.Recognize(context.Background(), make([]byte, n))
		if err != nil {
			t.Fatal(err)
		}
		if got, want := r.Text(), strings.Repeat("あ", n)+"い"; got != want {
			t.Fatalf("got %q, want %q", got, want)
		}
	}
}

func TestClientIdleRestart(t *testing.T) {
	c := fake(t, 50*time.Millisecond)
	if _, err := c.Recognize(context.Background(), []byte{1}); err != nil {
		t.Fatal(err)
	}
	time.Sleep(200 * time.Millisecond)
	c.mu.Lock()
	running := c.cmd != nil
	c.mu.Unlock()
	if running {
		t.Fatal("helper still running after the idle timeout")
	}
	if _, err := c.Recognize(context.Background(), []byte{1, 2}); err != nil {
		t.Fatal("restart:", err)
	}
}
