package codec

import (
	"encoding/json"
	"errors"
)

type Codec interface {
	Marshal(v interface{}) ([]byte, error)
	Unmarshal(data []byte, v interface{}) error
}

var defaultCodec Codec = &JSONCodec{}

func Marshal(v interface{}) ([]byte, error) {
	return defaultCodec.Marshal(v)
}

func Unmarshal(data []byte, v interface{}) error {
	return defaultCodec.Unmarshal(data, v)
}

type JSONCodec struct {
}

func (c *JSONCodec) Marshal(v interface{}) ([]byte, error) {
	return json.Marshal(v)
}

func (c *JSONCodec) Unmarshal(data []byte, v interface{}) error {
	return json.Unmarshal(data, v)
}

type protobuf interface {
	Marshal() (data []byte, err error)
	Unmarshal(data []byte) error
}

type PBCodec struct {
}

var ErrorPB = errors.New("is not Protobuf")

func (c *PBCodec) Marshal(v interface{}) ([]byte, error) {
	if p, ok := v.(protobuf); ok {
		return p.Marshal()
	}
	return nil, ErrorPB
}

func (c *PBCodec) Unmarshal(data []byte, v interface{}) error {
	if p, ok := v.(protobuf); ok {
		return p.Unmarshal(data)
	}
	return ErrorPB
}
