package registry_test

import (
	"flow/internal/assert"
	"flow/registry"
	"testing"
)

func TestNewEntryInvalid(t *testing.T) {
	a := assert.A(t)
	r := registry.New()
	e := registry.NewEntry(r, "string")
	a.Eq(e.Err(), registry.ErrNotAFunc, "entry is not a function")
}
func TestNewEntryValid(t *testing.T) {
	a := assert.A(t)
	r := registry.New()
	e := registry.NewEntry(r, func(a int) int { return 0 })
	a.Eq(e.Err(), nil, "fetching an entry")
}

func TestDescription(t *testing.T) {
	a := assert.A(t)
	r := registry.New()

	e := registry.NewEntry(r, func(a int) int { return 0 })
	e.Tags("a", "b")
	a.Eq(e.Err(), nil, "should not fail setting categories")
	a.Eq(len(e.Description.Tags), 2, "should have 2 categories")
	a.Eq(len(e.Description.Inputs), 1, "Should have 2 input description")

	e2 := registry.NewEntry(r, func(a, b int) int { return 0 })
	a.Eq(len(e2.Description.Inputs), 2, "Should have 2 input description")

	e.DescInputs("input")
	a.Eq(e.Err(), nil, "should not fail setting input name")
	a.Eq(e.Description.Inputs[0].Name, "input", "should have the input description")

	e.DescInputs("input", "2", "3")
	a.Eq(len(e.Description.Inputs), 1, "should have only one input")

	e.DescOutput("output name")
	a.Eq(e.Err(), nil, "should not fail setting input description")
	a.Eq(e.Description.Output.Name, "output name", "output description should be the same")

	e.Extra("test", 123)
	a.Eq(e.Err(), nil, "should not fail setting extra doc")
	a.Eq(e.Description.Extra["test"], 123, "extra text should be as expected")
}

func TestDescriptionError(t *testing.T) {
	a := assert.A(t)
	r := registry.New()
	e := registry.NewEntry(r, "string")
	a.Eq(e.Err(), registry.ErrNotAFunc, "entry is not a function")
	e.Tags("a", "b")
	a.Eq(e.Err(), registry.ErrNotAFunc, "entry is not a function")
	e.DescInputs("input")
	a.Eq(e.Err(), registry.ErrNotAFunc, "entry is not a function")
	e.DescOutput("output")
	a.Eq(e.Err(), registry.ErrNotAFunc, "entry is not a function")
	e.Extra("test", 123)
	a.Eq(e.Err(), registry.ErrNotAFunc, "entry is not a function")

}

func TestEntryBatch(t *testing.T) {
	a := assert.A(t)
	r := registry.New()

	b := registry.Batch{
		registry.NewEntry(r, func() int { return 0 }),
		registry.NewEntry(r, func() int { return 0 }),
		registry.NewEntry(r, func() int { return 0 }),
	}.Tags("test").Extra("name", 1)

	a.Eq(len(b), 3, "should have 3 items")
	for _, e := range b {
		a.Eq(e.Description.Tags[0], "test", "It should be of category test")
		a.Eq(e.Description.Extra["name"], 1, "It should contain extra")
	}

}
