package migration

import "io"

// ActionLogObserver returns a non-owning live observer for one tenant's
// durable action log. Closing the returned writer must not close a process
// standard stream or a job-wide output stream.
type ActionLogObserver func(tenant string) io.WriteCloser

// LoopOutput separates command results, operator progress, and optional live
// observation of the durable per-tenant action log.
type LoopOutput struct {
	Result            io.Writer
	Progress          io.Writer
	ActionLogObserver ActionLogObserver
}

func (o LoopOutput) normalized() LoopOutput {
	if o.Result == nil {
		o.Result = io.Discard
	}
	if o.Progress == nil {
		o.Progress = io.Discard
	}
	return o
}

// ActionOutput separates concise operator progress from detailed action
// output. Log is persisted in the tenant action log; Progress is routed by the
// caller to the service's live job stream.
type ActionOutput struct {
	Progress io.Writer
	Log      io.Writer
}

func (o ActionOutput) normalized() ActionOutput {
	if o.Progress == nil {
		o.Progress = io.Discard
	}
	if o.Log == nil {
		o.Log = io.Discard
	}
	return o
}

type nopWriteCloser struct {
	io.Writer
}

func (nopWriteCloser) Close() error { return nil }

// ObserveWith adapts w into a non-owning ActionLogObserver.
func ObserveWith(w io.Writer) ActionLogObserver {
	if w == nil {
		return nil
	}
	return func(string) io.WriteCloser { return nopWriteCloser{Writer: w} }
}
