package modelse

import "time"

const (
	APP_NAME    = "app_name"
	APP_ID      = "app_id"
	AGENT_ID    = "agent_id"
	INSTANCE_ID = "instance_id"
)

type APP_TYPE int

const (
	APP_WAIT APP_TYPE = iota
	APP_SUCCESS
	APP_UPROBE_ERROR
	APP_STACK_ERROR
	APP_UNINSTALL
	APP_UNINSTALL_ERROR
	APP_FUSE
	APP_FUSE_ERROR
	APP_LICENSE_FUSE
	APP_LICENSE_FUSE_ERROR
)

const (
	TRACE_STATUS = 200
)

func (s APP_TYPE) Error() APP_TYPE {
	switch s {
	case APP_UNINSTALL:
		return APP_UNINSTALL_ERROR
	case APP_FUSE:
		return APP_FUSE_ERROR
	case APP_LICENSE_FUSE:
		return APP_LICENSE_FUSE_ERROR
	default:
		return APP_UPROBE_ERROR
	}
}
func (s APP_TYPE) IsSuccess() bool {
	if s == APP_SUCCESS {
		return true
	}
	return false
}

func (s APP_TYPE) IsError() bool {
	switch s {
	case APP_UNINSTALL_ERROR:
	case APP_FUSE_ERROR:
	case APP_LICENSE_FUSE_ERROR:
	case APP_UPROBE_ERROR:
		return true
	default:
		return false
	}
	return false
}

func (s APP_TYPE) String() string {
	switch s {
	case APP_SUCCESS:
		return "SUCCESS"
	case APP_UPROBE_ERROR:
		return "UPROBE ERROR"
	case APP_UNINSTALL:
		return "UNINSTALL"
	case APP_FUSE:
		return "FUSE"
	case APP_LICENSE_FUSE:
		return "LICENSE FUSE"
	default:
		return "-"
	}
}

type AppInfo struct {
	AppName        string        `json:"app_name"`
	AppIdHash      INT_HASH_ID   `json:"app_id_hash"`
	InstanceIdHash INT_HASH_ID   `json:"instance_id_hash"`
	AgentId        int64         `json:"agent_id"`
	Sn             string        `json:"sn"`
	Sport          int           `json:"sport"`
	ServiceType    string        `json:"service_name"`
	CodeType       CodeType      `json:"code_type"`
	EBPFProcInfo   *EbpfProcInfo `json:"ebpf_proc_info"`
	RegisterAt     int64         `json:"register_at"`
	UpdateAt       int64         `json:"update_at"`
	PreStatus      APP_TYPE      `json:"pre_status"`
	Status         APP_TYPE      `json:"status"`
	Version        string        `json:"version"`
	GoProcCache    ProcOnce      `json:"go_proc_cache"`
}

type ProcOnce struct {
	StartAddr uint64 `json:"start_addr"`
	EndAddr   uint64 `json:"end_addr"`
}

func (a *AppInfo) UpdateAtTime() {
	a.UpdateAt = time.Now().Unix()
}

func (a *AppInfo) SetAppStatus(status APP_TYPE) {
	a.PreStatus = a.Status
	a.Status = status
	a.UpdateAtTime()
}

func (a *AppInfo) SetAppSuccess() {
	if !a.Status.IsSuccess() {
		a.SetAppStatus(APP_SUCCESS)
	}
}

func (a *AppInfo) SetAppStackError() {
	a.SetAppStatus(APP_STACK_ERROR)
}

func (a *AppInfo) SetAppUprobeError() {
	a.SetAppStatus(APP_UPROBE_ERROR)
}

func (a *AppInfo) AppUninstall() {
	a.SetAppStatus(APP_UNINSTALL)
}
