package walker

import (
	"fmt"
	"os"
	"plugin"
	"time"
)

// LoadPlugin loads the file path and returns a Fuzzer
func LoadPlugin(path string) (Fuzzer, error) {
	p, err := plugin.Open(path)
	if err != nil {
		return nil, err
	}
	sym, err := p.Lookup("NewFuzzer")
	if err != nil {
		return nil, fmt.Errorf("LoadPlugin: %q", err)
	}
	nf, ok := sym.(func() (Fuzzer, error))
	if !ok {
		return nil, fmt.Errorf("LoadPlugin: plugin at %q did not provide a NewFuzzer function", path)
	}
	return nf()
}

// NewFuzzer initializes a new Fuzzer
type NewFuzzer func() (Fuzzer, error)

// Fuzzer is a struct that produces a FuzzFunc
type Fuzzer interface {
	Name() string
	Func(path string, info os.FileInfo, timeout time.Duration) error
}

// FuzzFunc is like filepath.WalkerFunc, but for poking at `path`
type FuzzFunc func(path string, info os.FileInfo, timeout time.Duration) error
