package ext

import (
	"encoding/json"
	"io"

	"gopkg.in/yaml.v2"
	yamlv3 "gopkg.in/yaml.v3"
)

type Encoding string

const (
	EncodingYML  Encoding = "yml"
	EncodingYAML Encoding = "yaml"
	EncodingJSON Encoding = "json"
)

func (e Encoding) NewEncoder(w io.Writer) EncodeCloser {
	switch e {
	case EncodingYML, EncodingYAML:
		return yaml.NewEncoder(w)
	case EncodingJSON:
		return NopCloseEncoder{json.NewEncoder(w)}
	}

	return nil
}

type Encoder interface {
	Encode(any) error
}

type EncodeCloser interface {
	Encoder
	Close() error
}

type NopCloseEncoder struct {
	Encoder
}

func (n NopCloseEncoder) Close() error { return nil }

func (e Encoding) NewDecoder(r io.Reader) Decoder {
	switch e {
	case EncodingYML, EncodingYAML:
		return yamlv3.NewDecoder(r)
	case EncodingJSON:
		return json.NewDecoder(r)
	}

	return nil
}

type Decoder interface {
	Decode(any) error
}
