package bizerr

type Optional struct {
	originalErr error
	finalErr    BizError
	broken      bool
}

func OfNullable() *Optional {
	return &Optional{}
}

func (p *Optional) BreakIf(executor func() BizError) *Optional {
	if p.broken {
		return p
	}
	if executor == nil {
		return p
	}
	if err := executor(); err != nil {
		p.originalErr = err
		p.finalErr = err
		p.broken = true
	}
	return p
}

func (p *Optional) BreakAndWrapIf(code ErrCode, msg string, executor func() error) *Optional {
	if p.broken {
		return p
	}
	if executor == nil {
		return p
	}
	if err := executor(); err != nil {
		p.originalErr = err
		p.finalErr = WrapErrorWithCode(err, code, "%s", msg)
		p.broken = true
	}
	return p
}

func (p *Optional) If(handle func(err BizError)) *Optional {
	if p.broken && handle != nil {
		handle(p.finalErr)
	}
	return p
}

func (p *Optional) Else(handle func(err BizError)) *Optional {
	if !p.broken && handle != nil {
		handle(p.finalErr)
	}
	return p
}

func (p *Optional) Present() BizError {
	return p.finalErr
}

func (p *Optional) IfPresent() bool {
	return p.broken
}

func (p *Optional) IfNil() bool {
	return !p.broken
}
