package media_test

import (
	"io"
	"testing"

	"git.netflux.io/rob/clipper/media"
	"github.com/stretchr/testify/assert"
)

type testReader struct {
	count int
	data  [][]byte
}

func (r *testReader) Read(p []byte) (int, error) {
	if r.count == len(r.data) {
		return 0, io.EOF
	}
	n := copy(p, r.data[r.count])
	r.count++
	return n, nil
}

func TestModuloBufReader(t *testing.T) {
	reader := testReader{
		data: [][]byte{
			{'a', 'b', 'c', 'd'},
			{'e', 'f', 'g', 'h', 'i'},
			{},
			{'j', 'k', 'l', 'm'},
			{'n', 'o', 'p'},
			{'q', 'r', 's', 't', 'u'},
		},
	}

	modReader := media.NewModuloReader(io.NopCloser(&reader), 4)

	out := make([]byte, 5)

	n, err := modReader.Read(out)
	assert.NoError(t, err)
	assert.Equal(t, 4, n)
	assert.Equal(t, []byte{'a', 'b', 'c', 'd'}, out[:n])

	n, err = modReader.Read(out)
	assert.NoError(t, err)
	assert.Equal(t, 4, n)
	assert.Equal(t, []byte{'e', 'f', 'g', 'h'}, out[:n])

	n, err = modReader.Read(out)
	assert.NoError(t, err)
	assert.Zero(t, n)
	assert.Empty(t, out[:n])

	n, err = modReader.Read(out)
	assert.NoError(t, err)
	assert.NoError(t, err)
	assert.Equal(t, 4, n)
	assert.Equal(t, []byte{'i', 'j', 'k', 'l'}, out[:n])

	n, err = modReader.Read(out)
	assert.NoError(t, err)
	assert.Equal(t, 4, n)
	assert.Equal(t, []byte{'m', 'n', 'o', 'p'}, out[:n])

	n, err = modReader.Read(out)
	assert.NoError(t, err)
	assert.Equal(t, 4, n)
	assert.Equal(t, []byte{'q', 'r', 's', 't'}, out[:n])

	n, err = modReader.Read(out)
	assert.Equal(t, io.EOF, err)
	assert.Equal(t, 1, n)
	assert.Equal(t, []byte{'u'}, out[:n])

	n, err = modReader.Read(out)
	assert.Zero(t, n)
	assert.Equal(t, io.EOF, err)
}
