//analyze xml message
package main

import (
	"encoding/xml"
)

//EncryptedMsg encrypted message from Wechat
type EncryptedMsg struct {
	ToUserName string
	Encrypt    string
}

//all xml message has these headers
type CommonHeader struct {
	ToUserName   string
	FromUserName string
	CreateTime   int64
	MsgType      string
}

//text message
type TextMsg struct {
	Content string
	MsgId   int64
}

//picture
type PicMsg struct {
	PicUrl  string
	MediaId string
	MsgId   int64
}

//voice
type VoiceMsg struct {
	MediaId     string
	Format      string
	MsgId       int64
	Recognition string
}

//video
type VideoMsg struct {
	MediaId      string
	ThumbMediaId string
	MsgId        int64
}

//short video
type ShortVideoMsg struct {
	MediaId      string
	ThumbMediaId string
	MsgId        int64
}

//Location Incoming Msg
type LocationMsg struct {
	Location_X float64
	Location_Y float64
	Scale      int
	Label      string
	MsgId      int64
}

type LinkMsg struct {
	Title       string
	Description string
	Url         string
	MsgId       int64
}

//EventMsg all type of event
type EventMsg struct {
	Event        string  //subscribe, unsubscribe, SCAN, LOCATION, CLICK, VIEW
	EventKey     string  //for CLICK, VIEW, SCAN, subscribe
	Ticket       string  //for SCAN, subscribe
	Latitude     float64 //for LOCATION
	Longitude    float64 //for LOCATION
	Precision    float64 //for LOCATION
	KfAccount    string  //for kf_close_session kf_create_session
	CloseType    string  //for kf_close_session
	ScanCodeInfo struct {
		ScanType   string //for scancode_push scancode_waitmsg
		ScanResult string
	}
	SendPicsInfo struct { //for pic_photo_or_album pic_weixin pic_sysphoto
		Count   int
		PicList struct {
			Item []struct {
				PicMd5Sum string
			} `xml:"item"`
		}
	}
}

//ReadCommonHeader parse xml of common field of wechat post message
func ReadCommonHeader(s string) CommonHeader {
	var r = CommonHeader{}
	xml.Unmarshal([]byte(s), &r)
	return r
}

//ReadTextMsg extract text message
func ReadTextMsg(s string) TextMsg {
	var r = TextMsg{}
	xml.Unmarshal([]byte(s), &r)
	return r
}

//ReadPicMsg extract text message
func ReadPicMsg(s string) PicMsg {
	var r = PicMsg{}
	xml.Unmarshal([]byte(s), &r)
	return r
}

//ReadVoiceMsg extract text message
func ReadVoiceMsg(s string) VoiceMsg {
	var r = VoiceMsg{}
	xml.Unmarshal([]byte(s), &r)
	return r
}

//ReadVideoMsg extract text message
func ReadVideoMsg(s string) VideoMsg {
	var r = VideoMsg{}
	xml.Unmarshal([]byte(s), &r)
	return r
}

//ReadShortVideoMsg extract text message
func ReadShortVideoMsg(s string) ShortVideoMsg {
	var r = ShortVideoMsg{}
	xml.Unmarshal([]byte(s), &r)
	return r
}

//ReadLocationMsg extract text message
func ReadLocationMsg(s string) LocationMsg {
	var r = LocationMsg{}
	xml.Unmarshal([]byte(s), &r)
	return r
}

//ReadLinkMsg extract text message
func ReadLinkMsg(s string) LinkMsg {
	var r = LinkMsg{}
	xml.Unmarshal([]byte(s), &r)
	return r
}

//ReadEncryptedMsg  get Encrypted Msg
func ReadEncryptedMsg(s string) EncryptedMsg {
	var r = EncryptedMsg{}
	xml.Unmarshal([]byte(s), &r)
	return r
}

//ReadEventMsg get event msg details
func ReadEventMsg(s string) EventMsg {
	var r = EventMsg{}
	xml.Unmarshal([]byte(s), &r)
	return r
}

//ReadEventType tells event type in string
//  subscribe
//  unsubscribe
//  scan
func ReadEventType(s string) string {
	var r = EventMsg{}
	xml.Unmarshal([]byte(s), &r)
	return r.Event
}

func decryptToXML(raw string) string {
	e := ReadEncryptedMsg(raw)
	sd := Decode(e.Encrypt)
	return sd
}
