// package use_group_link -- группа связей в вариантах использования
package use_group_link

import (
	"fmt"

	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
	"gitp78su.ipnodns.ru/svi/goarch/pkg/elems/elem_base"
)

// UseGroupLink -- группа связей в вариантах использования
type UseGroupLink struct {
	*elem_base.ElemBase
	Links_ []alias.Id `json:"link"` // Связи объекта
}

// NewUseGroupLink -- возвращает новый группу связей в вариантах использования
func NewUseGroupLink(elem map[string]interface{}) (*UseGroupLink, error) {
	elemBase, err := elem_base.NewElemBase(elem)
	if err != nil {
		return nil, fmt.Errorf("NewActor(): in create BaseSvg, err=\n\t%w", err)
	}

	id := elemBase.Id_
	_links0, isOk := elem["links"]
	if !isOk {
		return nil, fmt.Errorf("NewUseGroupLink(): id=%q, field `links` not found", id)
	}
	_links, isOk := _links0.([]interface{})
	if !isOk {
		return nil, fmt.Errorf("NewUseGroupLink(): id=%q, field `links`(%T, %+v) not []interface{}", id, _links0, _links0)
	}
	var links []alias.Id
	for _, _id := range _links {
		id0, isOk := _id.(string)
		if !isOk {
			return nil, fmt.Errorf("NewUseGroupLink(): id=%q, field `links`(%T, %+v) not string", id, _id, _id)
		}
		id1 := alias.Id(id0)
		if id1 == "" {
			return nil, fmt.Errorf("NewUseGroupLink(): id=%q, link=%q is empty", id, _id)
		}
		links = append(links, id1)
	}
	sf := &UseGroupLink{
		ElemBase: elemBase,
		Links_:   links,
	}
	return sf, nil
}

// Check -- проверяет ошибки связей
func (sf *UseGroupLink) Check(mapElem map[alias.Id]types.IElemDrawer) string {
	var msgErr string
	if len(sf.Links_) == 0 {
		msgErr = "Список ссылок(links) пуст\n"
	}
	// Проверить, что ссылки реально существует
	for _, id := range sf.Links_ {
		link, ok := mapElem[id]
		if !ok {
			msgErr += fmt.Sprintf("UseGroupLink.Check(): ссылка %q не существует\n", id)
			continue
		}
		ln, isOk := link.(types.ILinker)
		if !isOk {
			msgErr += fmt.Sprintf("UseGroupLink.Check(): ссылка %q не ILinker\n", id)
			continue
		}
		if !(ln.SrcId() == sf.Id() || ln.DstId() == sf.Id()) {
			msgErr += fmt.Sprintf("UseGroupLink.Check(): ссылка %q не взаимная\n", id)
			continue
		}
	}
	return msgErr
}

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