func (m *Manager) OccupySpecificBed(locationName string, bedName string) (*ir.PatientLocation, error) {
	roomManager, ok := m.RoomManagers[locationName]
	if !ok {
		return nil, fmt.Errorf("%s: %s", unknownLocation, locationName)
	}
	if roomManager.isBedOccupied[bedName] {
		return nil, fmt.Errorf("bed %q in location %q already occupied", bedName, locationName)
	}
	roomManager.isBedOccupied[bedName] = true
	roomManager.occupiedBeds++
	counters.SimulatedHospital.OccupiedBeds.With(prometheus.Labels{
		"poc": locationName,
	}).Set(float64(roomManager.occupiedBeds))
	log.Debugf("Occupied beds in %s: %d", locationName, roomManager.occupiedBeds)
	return &ir.PatientLocation{
		Poc:          roomManager.Poc,
		Room:         roomManager.Room,
		Bed:          bedName,
		Facility:     roomManager.Facility,
		LocationType: roomManager.Type,
		Building:     roomManager.Building,
		Floor:        roomManager.Floor,
	}, nil
}
OccupySpecificBed occupies the given bed in the given location.
Returns an error if the location doesn't exist, or the bed is already occupied.
package location
import (
	"context"
	"fmt"
	"github.com/pkg/errors"
	"github.com/prometheus/client_golang/prometheus"
	"gopkg.in/yaml.v2"
	"github.com/google/simhospital/pkg/files"
	"github.com/google/simhospital/pkg/ir"
	"github.com/google/simhospital/pkg/logging"
	"github.com/google/simhospital/pkg/monitoring"
)
const aAndEID = "ED"
var (
	unknownLocation = "unknown location"
	counters        struct {
		SimulatedHospital struct {
			OccupiedBeds *prometheus.GaugeVec `help:"Number of occupied beds" labels:"poc"`
		}
	}
	log = logging.ForCallerPackage()
)
type Manager struct {
	RoomManagers map[string]*RoomManager
}
type RoomManager struct {
	Poc      string
	Facility string
	Building string
	Floor    string
	Room     string
	Type     string
	occupiedBeds int
	isBedOccupied map[string]bool
}
func init() {
	if err := monitoring.CreateAndRegisterMetricsFromStruct(&counters); err != nil {
		log.WithError(err).Fatal("Cannot register metrics from the 'location' package")
	}
}
func NewManager(ctx context.Context, fileName string) (*Manager, error) {
	roomManagers := map[string]*RoomManager{}
	data, err := files.Read(ctx, fileName)
	if err != nil {
		return nil, errors.Wrapf(err, "cannot parse locations file %s", fileName)
	}
	if err = yaml.Unmarshal(data, &roomManagers); err != nil {
		return nil, errors.Wrapf(err, "cannot unmarshal locations from file %s", fileName)
	}
	log.WithField("file", fileName).Infof("Found %d locations", len(roomManagers))
	for n, rm := range roomManagers {
		t := rm.Type
		if t == "" {
			t = "BED"
		}
		roomManagers[n] = &RoomManager{
			Poc:           rm.Poc,
			Facility:      rm.Facility,
			Building:      rm.Building,
			Floor:         rm.Floor,
			Room:          rm.Room,
			Type:          t,
			occupiedBeds:  0,
			isBedOccupied: make(map[string]bool),
		}
		log.Infof(" - id: %s, poc: %s", n, rm.Poc)
	}
	if _, ok := roomManagers[aAndEID]; !ok {
		return nil, fmt.Errorf("no ED Location found, this is a required Location. File: %s", fileName)
	}
	return &Manager{RoomManagers: roomManagers}, nil
}
func (m *Manager) GetAAndELocation() *ir.PatientLocation {
	roomManager := m.RoomManagers[aAndEID]
	if roomManager == nil {
		return &ir.PatientLocation{LocationType: "ED"}
	}
	return &ir.PatientLocation{
		Poc:          roomManager.Poc,
		Facility:     roomManager.Facility,
		LocationType: roomManager.Type,
		Building:     roomManager.Building,
	}
}
func (m *Manager) OccupyAvailableBed(locationName string) (*ir.PatientLocation, error) {
	if _, ok := m.RoomManagers[locationName]; !ok {
		return nil, fmt.Errorf("%s: %s", unknownLocation, locationName)
	}
	for i := 1; ; i++ {
		bedName := fmt.Sprintf("Bed %d", i)
		if location, err := m.OccupySpecificBed(locationName, bedName); err == nil {
			return location, nil
		}
	}
}