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

import (
	"fmt"

	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
	"gitp78su.ipnodns.ru/svi/goarch/lev1/arch_node"
	"gitp78su.ipnodns.ru/svi/goarch/lev1/view_coord"
	"gitp78su.ipnodns.ru/svi/goarch/lev1/view_offset"
)

// ArchGroupLink -- группа связей
type ArchGroupLink struct {
	*arch_node.ArchNode
	Links_ []alias.ArchId `yaml:"link"` // Связи объекта
}

// NewUseGroupLink -- возвращает новый группу связей в вариантах использования
func NewUseGroupLink(elemBase *arch_node.ArchNode, id alias.ArchId, label_ alias.ArchText,
	labelCoord *view_coord.ViewCoord, labelOffset *view_offset.Offset,
	type_ alias.ArchType, elem map[string]interface{}, binElem []byte) (*ArchGroupLink, 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.ArchId
	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.ArchId(id0)
		if id1 == "" {
			return nil, fmt.Errorf("NewUseGroupLink(): id=%q, link=%q is empty", id, _id)
		}
		links = append(links, id1)
	}
	sf := &ArchGroupLink{
		ArchNode: elemBase,
		Links_:   links,
	}
	return sf, nil
}

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

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