package netlink

import (
	"fmt"
	"net"
	"strings"
	"syscall"

	"github.com/vishvananda/netlink/nl"
)

type PDP struct {
	Version     uint32
	TID         uint64
	PeerAddress net.IP
	MSAddress   net.IP
	Flow        uint16
	NetNSFD     uint32
	ITEI        uint32
	OTEI        uint32
}

func (pdp *PDP) String() string {
	elems := []string{}
	elems = append(elems, fmt.Sprintf("Version: %d", pdp.Version))
	if pdp.Version == 0 {
		elems = append(elems, fmt.Sprintf("TID: %d", pdp.TID))
	} else if pdp.Version == 1 {
		elems = append(elems, fmt.Sprintf("TEI: %d/%d", pdp.ITEI, pdp.OTEI))
	}
	elems = append(elems, fmt.Sprintf("MS-Address: %s", pdp.MSAddress))
	elems = append(elems, fmt.Sprintf("Peer-Address: %s", pdp.PeerAddress))
	return fmt.Sprintf("{%s}", strings.Join(elems, " "))
}

func (p *PDP) parseAttributes(attrs []syscall.NetlinkRouteAttr) error {
	for _, a := range attrs {
		switch a.Attr.Type {
		case nl.GENL_GTP_ATTR_VERSION:
			p.Version = native.Uint32(a.Value)
		case nl.GENL_GTP_ATTR_TID:
			p.TID = native.Uint64(a.Value)
		case nl.GENL_GTP_ATTR_PEER_ADDRESS:
			p.PeerAddress = net.IP(a.Value)
		case nl.GENL_GTP_ATTR_MS_ADDRESS:
			p.MSAddress = net.IP(a.Value)
		case nl.GENL_GTP_ATTR_FLOW:
			p.Flow = native.Uint16(a.Value)
		case nl.GENL_GTP_ATTR_NET_NS_FD:
			p.NetNSFD = native.Uint32(a.Value)
		case nl.GENL_GTP_ATTR_I_TEI:
			p.ITEI = native.Uint32(a.Value)
		case nl.GENL_GTP_ATTR_O_TEI:
			p.OTEI = native.Uint32(a.Value)
		}
	}
	return nil
}

func parsePDP(msgs [][]byte) ([]*PDP, error) {
	pdps := make([]*PDP, 0, len(msgs))
	for _, m := range msgs {
		attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:])
		if err != nil {
			return nil, err
		}
		pdp := &PDP{}
		if err := pdp.parseAttributes(attrs); err != nil {
			return nil, err
		}
		pdps = append(pdps, pdp)
	}
	return pdps, nil
}

func (h *Handle) GTPPDPList() ([]*PDP, error) {
	f, err := h.GenlFamilyGet(nl.GENL_GTP_NAME)
	if err != nil {
		return nil, err
	}
	msg := &nl.Genlmsg{
		Command: nl.GENL_GTP_CMD_GETPDP,
		Version: nl.GENL_GTP_VERSION,
	}
	req := h.newNetlinkRequest(int(f.ID), syscall.NLM_F_DUMP)
	req.AddData(msg)
	msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0)
	if err != nil {
		return nil, err
	}
	return parsePDP(msgs)
}

func GTPPDPList() ([]*PDP, error) {
	return pkgHandle.GTPPDPList()
}

func gtpPDPGet(req *nl.NetlinkRequest) (*PDP, error) {
	msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0)
	if err != nil {
		return nil, err
	}
	pdps, err := parsePDP(msgs)
	if err != nil {
		return nil, err
	}
	if len(pdps) != 1 {
		return nil, fmt.Errorf("invalid reqponse for GENL_GTP_CMD_GETPDP")
	}
	return pdps[0], nil
}

func (h *Handle) GTPPDPByTID(link Link, tid int) (*PDP, error) {
	f, err := h.GenlFamilyGet(nl.GENL_GTP_NAME)
	if err != nil {
		return nil, err
	}
	msg := &nl.Genlmsg{
		Command: nl.GENL_GTP_CMD_GETPDP,
		Version: nl.GENL_GTP_VERSION,
	}
	req := h.newNetlinkRequest(int(f.ID), 0)
	req.AddData(msg)
	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(0)))
	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_LINK, nl.Uint32Attr(uint32(link.Attrs().Index))))
	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_TID, nl.Uint64Attr(uint64(tid))))
	return gtpPDPGet(req)
}

func GTPPDPByTID(link Link, tid int) (*PDP, error) {
	return pkgHandle.GTPPDPByTID(link, tid)
}

func (h *Handle) GTPPDPByITEI(link Link, itei int) (*PDP, error) {
	f, err := h.GenlFamilyGet(nl.GENL_GTP_NAME)
	if err != nil {
		return nil, err
	}
	msg := &nl.Genlmsg{
		Command: nl.GENL_GTP_CMD_GETPDP,
		Version: nl.GENL_GTP_VERSION,
	}
	req := h.newNetlinkRequest(int(f.ID), 0)
	req.AddData(msg)
	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(1)))
	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_LINK, nl.Uint32Attr(uint32(link.Attrs().Index))))
	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_I_TEI, nl.Uint32Attr(uint32(itei))))
	return gtpPDPGet(req)
}

func GTPPDPByITEI(link Link, itei int) (*PDP, error) {
	return pkgHandle.GTPPDPByITEI(link, itei)
}

func (h *Handle) GTPPDPByMSAddress(link Link, addr net.IP) (*PDP, error) {
	f, err := h.GenlFamilyGet(nl.GENL_GTP_NAME)
	if err != nil {
		return nil, err
	}
	msg := &nl.Genlmsg{
		Command: nl.GENL_GTP_CMD_GETPDP,
		Version: nl.GENL_GTP_VERSION,
	}
	req := h.newNetlinkRequest(int(f.ID), 0)
	req.AddData(msg)
	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(0)))
	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_LINK, nl.Uint32Attr(uint32(link.Attrs().Index))))
	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_MS_ADDRESS, []byte(addr.To4())))
	return gtpPDPGet(req)
}

func GTPPDPByMSAddress(link Link, addr net.IP) (*PDP, error) {
	return pkgHandle.GTPPDPByMSAddress(link, addr)
}

func (h *Handle) GTPPDPAdd(link Link, pdp *PDP) error {
	f, err := h.GenlFamilyGet(nl.GENL_GTP_NAME)
	if err != nil {
		return err
	}
	msg := &nl.Genlmsg{
		Command: nl.GENL_GTP_CMD_NEWPDP,
		Version: nl.GENL_GTP_VERSION,
	}
	req := h.newNetlinkRequest(int(f.ID), syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
	req.AddData(msg)
	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(pdp.Version)))
	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_LINK, nl.Uint32Attr(uint32(link.Attrs().Index))))
	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_PEER_ADDRESS, []byte(pdp.PeerAddress.To4())))
	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_MS_ADDRESS, []byte(pdp.MSAddress.To4())))

	switch pdp.Version {
	case 0:
		req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_TID, nl.Uint64Attr(pdp.TID)))
		req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_FLOW, nl.Uint16Attr(pdp.Flow)))
	case 1:
		req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_I_TEI, nl.Uint32Attr(pdp.ITEI)))
		req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_O_TEI, nl.Uint32Attr(pdp.OTEI)))
	default:
		return fmt.Errorf("unsupported GTP version: %d", pdp.Version)
	}
	_, err = req.Execute(syscall.NETLINK_GENERIC, 0)
	return err
}

func GTPPDPAdd(link Link, pdp *PDP) error {
	return pkgHandle.GTPPDPAdd(link, pdp)
}

func (h *Handle) GTPPDPDel(link Link, pdp *PDP) error {
	f, err := h.GenlFamilyGet(nl.GENL_GTP_NAME)
	if err != nil {
		return err
	}
	msg := &nl.Genlmsg{
		Command: nl.GENL_GTP_CMD_DELPDP,
		Version: nl.GENL_GTP_VERSION,
	}
	req := h.newNetlinkRequest(int(f.ID), syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
	req.AddData(msg)
	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(pdp.Version)))
	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_LINK, nl.Uint32Attr(uint32(link.Attrs().Index))))

	switch pdp.Version {
	case 0:
		req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_TID, nl.Uint64Attr(pdp.TID)))
	case 1:
		req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_I_TEI, nl.Uint32Attr(pdp.ITEI)))
	default:
		return fmt.Errorf("unsupported GTP version: %d", pdp.Version)
	}
	_, err = req.Execute(syscall.NETLINK_GENERIC, 0)
	return err
}

func GTPPDPDel(link Link, pdp *PDP) error {
	return pkgHandle.GTPPDPDel(link, pdp)
}
