type AttrSplitor struct {
	attrMapList []map[string]interface{}
}

func NewSplitor(attrList ...map[string]interface{}) *AttrSplitor {
	return &AttrSplitor{attrMapList: attrList}
}

func (l *AttrSplitor) Split(src map[string]json.RawMessage) (result []map[string]json.RawMessage, err error) {
	for _, attrMap := range l.attrMapList {
		part := make(map[string]json.RawMessage)
		for key, obj := range attrMap {
			rawValue, ok := src[key]
			if !ok {
				continue
			}
			val := reflect.New(reflect.TypeOf(obj))
			err = json.Unmarshal(rawValue, val.Interface())
			if err != nil {
				return
			}
			part[key], err = json.Marshal(val.Interface())
			if err != nil {
				return
			}
		}
		result = append(result, part)
	}
	return
}

type AttachmentType string

const (
	ATTACHMENT_TYPE_IPLINK_STATIC = "ip_link_static"
	ATTACHMENT_TYPE_IPLINK_PPPOE  = "ip_link_pppoe"
	ATTACHMENT_TYPE_IPLINK_VPN    = "ip_link_vpn"
	ATTACHMENT_TYPE_UNKNOWN       = "unknown"
)

var AttachmentAttrSplitor map[AttachmentType]*AttrSplitor

func init() {
	AttachmentAttrSplitor = map[AttachmentType]*AttrSplitor{
		ATTACHMENT_TYPE_IPLINK_STATIC: NewSplitor(
			map[string]interface{}{
				"vlan":        uint32(0),
				"mac":         HardwareAddr{},
				"ip_mask":     IPMask{},
				"gateway":     "",
				"max_tx":      uint32(0),
				"max_rx":      uint32(0),
				"ac_name":     "",
				"server_name": "",
			},
			map[string]interface{}{
				"bridge": "",
			},
		),
		ATTACHMENT_TYPE_IPLINK_PPPOE: NewSplitor(
			map[string]interface{}{
				"vlan":        uint32(0),
				"mac":         HardwareAddr{},
				"username":    "",
				"password":    "",
				"max_tx":      uint32(0),
				"max_rx":      uint32(0),
				"ac_name":     "",
				"server_name": "",
			},
			map[string]interface{}{
				"bridge": "",
			},
		),
	}
}