package storage

import (
	"context"
	"crypto/md5"
	"encoding/hex"
	"errors"
	"io"
	"strings"
	"testing"
)

func TestComposeStreams(t *testing.T) {
	objects := map[string]string{"a": "hello ", "b": "world"}
	var stored string
	hash, err := composeStreams(context.Background(), []string{"a", "b"}, func(_ context.Context, name string) (io.ReadCloser, error) {
		value, ok := objects[name]
		if !ok {
			return nil, errors.New("missing object")
		}
		return io.NopCloser(strings.NewReader(value)), nil
	}, func(_ context.Context, _ string, reader io.Reader) error {
		value, err := io.ReadAll(reader)
		stored = string(value)
		return err
	}, func(context.Context, string) error { return nil }, "out")
	if err != nil || stored != "hello world" {
		t.Fatalf("compose = %q, %v", stored, err)
	}
	want := md5.Sum([]byte(stored))
	if hash != hex.EncodeToString(want[:]) {
		t.Fatalf("hash = %q", hash)
	}
}

func TestComposeStreamsRemovesPartialDestination(t *testing.T) {
	removed := false
	_, err := composeStreams(context.Background(), []string{"missing"}, func(context.Context, string) (io.ReadCloser, error) {
		return nil, errors.New("open failed")
	}, func(_ context.Context, _ string, reader io.Reader) error {
		_, _ = io.ReadAll(reader)
		return nil
	}, func(context.Context, string) error {
		removed = true
		return nil
	}, "out")
	if err == nil || !removed {
		t.Fatalf("compose error = %v, removed = %v", err, removed)
	}
}
