package nucleus

import (
	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkdomain"
	"code.fbi.h-da.de/danet/gosdn/controller/store"
	"github.com/google/uuid"
)

// PndService provides a PND service implementation.
type PndService struct {
	pndStore networkdomain.PndStore
}

// NewPndService creates a PND service.
func NewPndService(pndStore networkdomain.PndStore) networkdomain.Service {
	pndService := &PndService{
		pndStore: pndStore,
	}

	return pndService
}

// Add adds a PND to the PND store.
func (p *PndService) Add(pndToAdd networkdomain.NetworkDomain) error {
	err := p.pndStore.Add(pndToAdd)
	if err != nil {
		return err
	}

	return nil
}

// Delete deletes a PND from the PND store.
func (p *PndService) Delete(pndToDelete networkdomain.NetworkDomain) error {
	err := p.pndStore.Delete(pndToDelete)
	if err != nil {
		return err
	}

	return nil
}

// Get takes a PND's UUID or name and returns the PND.
func (p *PndService) Get(query store.Query) (networkdomain.NetworkDomain, error) {
	loadedPnd, err := p.pndStore.Get(query)
	if err != nil {
		return nil, err
	}

	return p.createPndFromStore(loadedPnd), nil
}

// GetAll returns all stores PNDs.
func (p *PndService) GetAll() ([]networkdomain.NetworkDomain, error) {
	var pnds []networkdomain.NetworkDomain

	loadedPnds, err := p.pndStore.GetAll()
	if err != nil {
		return nil, err
	}

	for _, loadedPnd := range loadedPnds {
		pnds = append(pnds, p.createPndFromStore(loadedPnd))
	}

	return pnds, nil
}

func (p *PndService) createPndFromStore(loadedPnd networkdomain.LoadedPnd) networkdomain.NetworkDomain {
	return NewPND(uuid.MustParse(loadedPnd.ID), loadedPnd.Name, loadedPnd.Description)
}
