package sources

import (
	"context"
	"errors"
	"fmt"

	"github.com/atotto/clipboard"

	"github.com/salvacybersec/keyhunter/pkg/types"
)

// ClipboardSource reads the current OS clipboard contents and emits them
// as a single chunk stream with Source="clipboard". Requires xclip/xsel/
// wl-clipboard on Linux, pbpaste on macOS, or native API on Windows.
type ClipboardSource struct {
	// Reader overrides the clipboard reader; when nil the real clipboard is used.
	// Tests inject a func returning a fixture.
	Reader    func() (string, error)
	ChunkSize int
}

// NewClipboardSource returns a ClipboardSource bound to the real OS clipboard.
func NewClipboardSource() *ClipboardSource {
	return &ClipboardSource{Reader: clipboard.ReadAll, ChunkSize: defaultChunkSize}
}

// Chunks reads the clipboard and emits its contents.
func (c *ClipboardSource) Chunks(ctx context.Context, out chan<- types.Chunk) error {
	if clipboard.Unsupported && c.Reader == nil {
		return errors.New("ClipboardSource: clipboard tooling unavailable (install xclip/xsel/wl-clipboard on Linux)")
	}
	reader := c.Reader
	if reader == nil {
		reader = clipboard.ReadAll
	}
	text, err := reader()
	if err != nil {
		return fmt.Errorf("ClipboardSource: read: %w", err)
	}
	if text == "" {
		return nil
	}
	return emitByteChunks(ctx, []byte(text), "clipboard", c.ChunkSize, out)
}
