// package group_link -- группа связей
package group_link

import (
	"fmt"

	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
	"gitp78su.ipnodns.ru/svi/goarch/lev1/coord"
	"gitp78su.ipnodns.ru/svi/goarch/lev1/elem_base"
	"gitp78su.ipnodns.ru/svi/goarch/lev1/offset"
)

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

// NewUseGroupLink -- возвращает новый группу связей в вариантах использования
func NewUseGroupLink(elemBase *elem_base.ElemBase, id alias.Id, label_ alias.Label,
	labelCoord *coord.Coord, labelOffset *offset.Offset,
	type_ alias.Type, elem map[string]interface{}, binElem []byte) (*GroupLink, error) {
	_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 := &GroupLink{
		ElemBase_: elemBase,
		Links_:    links,
	}
	return sf, nil
}

// Check -- проверяет ошибки связей
func (sf *GroupLink) Check(mapElem map[alias.Id]types.IDrawer) 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.IElemLink)
		if !isOk {
			msgErr += fmt.Sprintf("UseGroupLink.Check(): ссылка %q не ILinker\n", id)
			continue
		}
		if !(ln.Src().Id() == sf.ElemBase_.Id_ || ln.Dst().Id() == sf.ElemBase_.Id_) {
			msgErr += fmt.Sprintf("UseGroupLink.Check(): ссылка %q не взаимная\n", id)
			continue
		}
	}
	return msgErr
}

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