package outcome

import (
	"encoding/gob"

	"hakurei.app/check"
	"hakurei.app/hst"
	"hakurei.app/internal/pipewire"
)

const pipewirePulseName = "pipewire-pulse"

func init() { gob.Register(new(spPipeWireOp)) }

// spPipeWireOp exports the PipeWire server to the container via SecurityContext.
//
// Runs after spRuntimeOp.
type spPipeWireOp struct {
	// Path to pipewire-pulse server.
	//
	// Populated during toSystem if DirectPipeWire is false.
	CompatServerPath *check.Absolute
}

func (s *spPipeWireOp) toSystem(state *outcomeStateSys) error {
	if state.et&hst.EPipeWire == 0 {
		return errNotEnabled
	}
	if !state.directPipeWire {
		if n, err := state.k.lookPath(pipewirePulseName); err != nil {
			return &hst.AppError{Step: "look up " + pipewirePulseName, Err: err}
		} else if s.CompatServerPath, err = check.NewAbs(n); err != nil {
			return err
		}
	}

	appId := state.appId
	if appId == "" {
		// use instance ID in case app id is not set
		appId = "app.hakurei." + state.id.String()
	}
	state.sys.PipeWire(state.instance().Append("pipewire"), appId, state.id.String())
	return nil
}

func (s *spPipeWireOp) toContainer(state *outcomeStateParams) error {
	if s.CompatServerPath == nil {
		innerPath := state.runtimeDir.Append(pipewire.PW_DEFAULT_REMOTE)
		state.env[pipewire.Remote] = innerPath.String()
		state.params.Bind(state.instancePath().Append("pipewire"), innerPath, 0)
	}

	// pipewire-pulse behaviour implemented in shim.go
	state.pipewirePulsePath = s.CompatServerPath
	return nil
}
