package asaModels

import (
	"regexp"

	"github.rackspace.com/gorax/tools/util"
)

var (
	RACONNRE       = regexp.MustCompile(`(?i)(|u)(sername\s+:(.|\n)*?)(\nu|$)`)
	RAUSERRE       = regexp.MustCompile(`(?i)sername\s+:\s+(\S+)`)
	RAASSIGNEDIPRE = regexp.MustCompile(`(?i)assigned\s+ip\s+:\s+(\S+)`)
	RAPUBLICIPRE   = regexp.MustCompile(`(?i)public\s+ip\s+:\s+(\S+)`)
	RATUNNELGRPRE  = regexp.MustCompile(`(?i)tunnel\s+group\s+:\s+(\S+)`)
	RAGROUPPOLRE   = regexp.MustCompile(`(?i)group\s+policy\s+:\s+(\S+)`)
	RAINACTRE      = regexp.MustCompile(`(?i)inactivity\s+:\s+(\S+)`)
	L2LCONNRE      = regexp.MustCompile(`(?i)(|c)(onnection\s+:(.|\n)*?)(\nc|$)`)
	L2LCONNNAMERE  = regexp.MustCompile(`onnection\s+:\s+(\S+)`)
	L2LINDEXRE     = regexp.MustCompile(`(?i)index\s+:\s+([0-9]+)`)
	L2LIPADDRE     = regexp.MustCompile(`(?i)ip\s+addr\s+:\s+(\S+)`)
	L2LPROTORE     = regexp.MustCompile(`(?i)protocol\s+:\s+(\S+)`)
	L2LENCRE       = regexp.MustCompile(`(?i)encryption\s+:\s+(\S+)`)
	L2LHASHRE      = regexp.MustCompile(`(?i)hashing\s+:\s+(\S+)`)
	L2LBYTETXRE    = regexp.MustCompile(`(?i)bytes\s+tx\s+:\s+([0-9]+)`)
	L2LBYTERXRE    = regexp.MustCompile(`(?i)bytes\s+rx\s+:\s+([0-9]+)`)
	L2LLOGINRE     = regexp.MustCompile(`(?i)login\s+time\s+:\s+(.*?)(\r|\n)`)
	L2LDURATIONRE  = regexp.MustCompile(`(?i)duration\s+:\s+(\S+)`)
)

type (
	Lan2Lans struct {
		Lan2Lans []*Lan2Lan `json:"l2l_tunnels"`
	}

	RATunnels struct {
		RATunnels []*RATunnel `json:"remote_access_tunnels"`
	}

	RATunnel struct {
		Username    *string `json:"username"`
		Index       *int    `json:"index"`
		AssignedIP  *string `json:"assigned_ip"`
		PublicIP    *string `json:"public_ip"`
		Protocol    *string `json:"protocol"`
		Encryption  *string `json:"encryption"`
		Hashing     *string `json:"hashing"`
		GroupPolicy *string `json:"group_policy"`
		TunnelGroup *string `json:"tunnel_group"`
		BytesTx     *int    `json:"bytes_tx"`
		BytesRx     *int    `json:"bytes_rx"`
		Login       *string `json:"login_time"`
		Duration    *string `json:"duration"`
		Inactivity  *string `json:"inactivity"`
	}

	Lan2Lan struct {
		Connection  *string `json:"connection"`
		Index       *int    `json:"index"`
		IpAddr      *string `json:"ip_addr"`
		Protocol    *string `json:"protocol"`
		Encryption  *string `json:"encryption"`
		Hashing     *string `json:"hashing"`
		GroupPolicy *string `json:"group_policy"`
		TunnelGroup *string `json:"tunnel_group"`
		BytesTx     *int    `json:"bytes_tx"`
		BytesRx     *int    `json:"bytes_rx"`
		Login       *string `json:"login_time"`
		Duration    *string `json:"duration"`
	}
)

func (l *Lan2Lans) Parse(s string) {
	for _, t := range L2LCONNRE.FindAllStringSubmatch(s, -1) {
		l.Lan2Lans = append(l.Lan2Lans, &Lan2Lan{
			Connection: util.RegexpFindStringPtr(L2LCONNNAMERE, t[2]),
			Index:      util.RegexpAtoiPtr(L2LINDEXRE, t[2]),
			IpAddr:     util.RegexpFindStringPtr(L2LIPADDRE, t[2]),
			Protocol:   util.RegexpFindStringPtr(L2LPROTORE, t[2]),
			Encryption: util.RegexpFindStringPtr(L2LENCRE, t[2]),
			Hashing:    util.RegexpFindStringPtr(L2LHASHRE, t[2]),
			BytesTx:    util.RegexpAtoiPtr(L2LBYTETXRE, t[2]),
			BytesRx:    util.RegexpAtoiPtr(L2LBYTERXRE, t[2]),
			Login:      util.RegexpFindStringPtr(L2LLOGINRE, t[2]),
			Duration:   util.RegexpFindStringPtr(L2LDURATIONRE, t[2]),
		})
	}
}

func (r *RATunnels) Parse(s string) {
	for _, t := range RACONNRE.FindAllStringSubmatch(s, -1) {
		r.RATunnels = append(r.RATunnels, &RATunnel{
			Username:    util.RegexpFindStringPtr(RAUSERRE, t[2]),
			Index:       util.RegexpAtoiPtr(L2LINDEXRE, t[2]),
			AssignedIP:  util.RegexpFindStringPtr(RAASSIGNEDIPRE, t[2]),
			PublicIP:    util.RegexpFindStringPtr(RAPUBLICIPRE, t[2]),
			Protocol:    util.RegexpFindStringPtr(L2LPROTORE, t[2]),
			Encryption:  util.RegexpFindStringPtr(L2LENCRE, t[2]),
			Hashing:     util.RegexpFindStringPtr(L2LHASHRE, t[2]),
			GroupPolicy: util.RegexpFindStringPtr(RAGROUPPOLRE, t[2]),
			TunnelGroup: util.RegexpFindStringPtr(RATUNNELGRPRE, t[2]),
			BytesTx:     util.RegexpAtoiPtr(L2LBYTETXRE, t[2]),
			BytesRx:     util.RegexpAtoiPtr(L2LBYTERXRE, t[2]),
			Login:       util.RegexpFindStringPtr(L2LLOGINRE, t[2]),
			Duration:    util.RegexpFindStringPtr(L2LDURATIONRE, t[2]),
			Inactivity:  util.RegexpFindStringPtr(RAINACTRE, t[2]),
		})
	}
}
