// package elem_use_case -- вариант использования
package elem_use_case

import (
	"fmt"

	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
	"gitp78su.ipnodns.ru/svi/goarch/lev0/cons"
	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
	"gitp78su.ipnodns.ru/svi/kern/v3"
)

// UseCase -- вариант использования
type UseCase struct {
	types.IElemBase
	Size_  types.ISize                       `yaml:"size"`
	Links_ map[alias.Id]types.IElemGroupLink `yaml:"links"` // Список ссылок
}

var (
	hassert = kern.GetFnHassert()
)

// NewUseCase -- возвращает новый вариант использования
func NewUseCase(elemBase types.IElemBase, size types.ISize,
	links map[alias.Id]types.IElemGroupLink) *UseCase {
	// id := elemBase.Id()
	// _links0, isOk := elemBase.Elem_["links"]
	// hassert(isOk, "NewUseCase(): id=%q, links not found", id)
	// _links, isOk := _links0.([]interface{})
	// hassert(isOk, "NewUseCase(): id=%q, `links`(%+v) not []interface{}", id, _links0)
	// for _, _id := range _links {
	// 	id0, isOk := _id.(string)
	// 	hassert(isOk, "NewUseCase(): id=%q, `link`(%T, %+v) not string", id, _id, _id)
	// 	id1 := alias.Id(id0)
	// 	hassert(id1 != "", "NewUseCase(): id=%q, `link` is empty", id)
	// 	links = append(links, id1)
	// }
	sf := &UseCase{
		IElemBase: elemBase,
		Size_:     size,
		Links_:    links,
	}
	sf.SelfCheck()
	return sf
}

// SelfCheck -- самопроверка
func (sf *UseCase) SelfCheck() {
	sf.IElemBase.SelfCheck()
	hassert(sf.Size_ != nil, "UseCase.SelfCheck(): Size_ == nil")
	var msgErr string
	// Нет ссылок
	if len(sf.Links_) == 0 {
		return
	}
	// Проверить, что ссылки реально существует
	for id, link := range sf.Links_ {
		if link.Type() != cons.TypeUseLink {
			msgErr += fmt.Sprintf("id=%q, не тип %q, тип=%q\n", id, cons.TypeUseLink, link.Type())
			continue
		}
		ln, isOk := link.(types.IElemLink)
		if !isOk {
			msgErr += fmt.Sprintf("id=%q, не тип `link`, link=%#v\n", id, link)
			continue
		}
		// Проверить что ссылка взаимная
		if !(ln.Src().Id() == sf.Id() || ln.Dst().Id() == sf.Id()) {
			msgErr += fmt.Sprintf("id=%q, ссылка не взаимная\nsrc=%q, dst=%q\n",
			id, ln.Src().Id(), ln.Dst().Id())
		}
	}
}

// Links -- ссылки вариантов использования
func (sf *UseCase) Links() map[alias.Id]types.IElemGroupLink {
	return sf.Links_
}
