// Code generated by go-varlink/varlinkgen. DO NOT EDIT.

package calcapi

import (
	"encoding/json"
	govarlink "github.com/emersion/go-varlink"
)

type DivisionByZeroError struct{}

func (err *DivisionByZeroError) Error() string {
	return "varlink call failed: org.example.calc.DivisionByZero"
}

type DivideIn struct {
	A int `json:"a"`
	B int `json:"b"`
}
type DivideOut struct {
	Result int `json:"result"`
}

type MultiplyIn struct {
	A int `json:"a"`
	B int `json:"b"`
}
type MultiplyOut struct {
	Result int `json:"result"`
}

type Client struct {
	*govarlink.Client
}

func unmarshalError(err error) error {
	verr, ok := err.(*govarlink.ClientError)
	if !ok {
		return err
	}
	var v error
	switch verr.Name {
	case "org.example.calc.DivisionByZero":
		v = new(DivisionByZeroError)
	default:
		return err
	}
	if err := json.Unmarshal(verr.Parameters, v); err != nil {
		return err
	}
	return v
}
func (c Client) Divide(in *DivideIn) (*DivideOut, error) {
	if in == nil {
		in = new(DivideIn)
	}
	out := new(DivideOut)
	err := c.Client.Do("org.example.calc.Divide", in, out)
	return out, unmarshalError(err)
}
func (c Client) Multiply(in *MultiplyIn) (*MultiplyOut, error) {
	if in == nil {
		in = new(MultiplyIn)
	}
	out := new(MultiplyOut)
	err := c.Client.Do("org.example.calc.Multiply", in, out)
	return out, unmarshalError(err)
}

type Backend interface {
	Divide(*DivideIn) (*DivideOut, error)
	Multiply(*MultiplyIn) (*MultiplyOut, error)
}

type Handler struct {
	Backend Backend
}

func marshalError(err error) error {
	var name string
	switch err.(type) {
	case *DivisionByZeroError:
		name = "org.example.calc.DivisionByZero"
	default:
		return err
	}
	return &govarlink.ServerError{
		Name:       name,
		Parameters: err,
	}
}
func (h Handler) HandleVarlink(call *govarlink.ServerCall, req *govarlink.ServerRequest) error {
	var (
		out interface{}
		err error
	)
	switch req.Method {
	case "org.example.calc.Divide":
		in := new(DivideIn)
		if err := json.Unmarshal(req.Parameters, in); err != nil {
			return err
		}
		out, err = h.Backend.Divide(in)
	case "org.example.calc.Multiply":
		in := new(MultiplyIn)
		if err := json.Unmarshal(req.Parameters, in); err != nil {
			return err
		}
		out, err = h.Backend.Multiply(in)
	default:
		err = &govarlink.ServerError{
			Name:       "org.varlink.service.MethodNotFound",
			Parameters: map[string]string{"method": req.Method},
		}
	}
	if err != nil {
		return marshalError(err)
	}
	return call.CloseWithReply(out)
}

func (h Handler) Register(reg *govarlink.Registry) {
	reg.Add(&govarlink.RegistryInterface{
		Definition: "interface org.example.calc\n\nerror DivisionByZero ()\n\nmethod Multiply(\n    a: int,\n    b: int\n) -> (result: int)\n\nmethod Divide(\n    a: int,\n    b: int\n) -> (result: int)\n",
		Name:       "org.example.calc",
	}, h)
}
