package modules

import "encoding/json"

//constantization of message type
const (
	KGM = 1 + iota	//KeyGenMessage
	KSM	//KeyShareMessage
	PM	//PublishMessage
	SM	//SubscriptionMessage
	RM	//RegisterMessage
	WM	//WithdrawMessage
)

//message form
type Message struct {
	From    string	// IP address of message's owner
	Version string	// message version
	Time    string	// time that creat message
	Kind    int		//message type
}

//message interface
type MsgUnit interface {
	ConvertToJson() ([]byte, error)	// member function of converting message to JSON form
	CheckType() int	// return message type
}

//***** message form and definition according to the message type*******

//Key generate message
type KeyGenMsg struct {
	Message
	iptable []string
}

//Key share message
type KeyShareMsg struct {
	Message
	key string
}

//publisher message
type PublishMsg struct {
	Message
	Topic   []int64 //attribute
	Value   []int64 //value
	Content []int64 //content
}

//subscrprion message
type SubscriptionMsg struct {
	Message
	Topic    []int64  //attribute
	Value    []int64  //value
	Operator []string //operator
	IsAlpha  bool     //value가 숫자인지 문자열인지, 문자열이면 단순비교, 숫자이면 범위연산
}

//message of register microservice
type RegisterMsg struct {
	Message
	PrivateKey int64
}

//message of remove microservice
type WithdrawMsg struct {
	Message
}

func (msg KeyGenMsg) ConvertToJson() ([]byte, error) {
	js := msg
	jsonBytes, err := json.Marshal(js)
	return jsonBytes, err
}

func (msg KeyShareMsg) ConvertToJson() ([]byte, error) {
	js := msg
	jsonBytes, err := json.Marshal(js)
	return jsonBytes, err
}

func (msg PublishMsg) ConvertToJson() ([]byte, error) {
	js := msg
	jsonBytes, err := json.Marshal(js)
	return jsonBytes, err
}

func (msg SubscriptionMsg) ConvertToJson() ([]byte, error) {
	js := msg
	jsonBytes, err := json.Marshal(js)
	return jsonBytes, err
}

func (msg RegisterMsg) ConvertToJson() ([]byte, error) {
	js := msg
	jsonBytes, err := json.Marshal(js)
	return jsonBytes, err
}

func (msg WithdrawMsg) ConvertToJson() ([]byte, error) {
	js := msg
	jsonBytes, err := json.Marshal(js)
	return jsonBytes, err
}

func (msg Message) CheckType() int {
	return msg.Kind
}

//constructor of key gen message
func NewKeyGenMsg(table *MStable) *KeyGenMsg {
	m := &KeyGenMsg{}
	for _, value := range table.NodeTable { // push IP address into IP table from microservice table
		m.iptable = append(m.iptable, value.GetIpaddr())
	}
	return m
}
