package modelse

import (
	"encoding/json"
	"fmt"
	log "github.com/sirupsen/logrus"
)

var (
	Ip            = ""
	StopAgent     = "agent_stop"
	StartAgent    = "agent_start"
	ReStartAgent  = "agent_restart"
	UpgradeAgent  = "agent_upgrade"
	RemoveAgent   = "agent_uninstall"
	InstallAgent  = "agent_install"
	FuseConf      = "daemon_fuse"
	RestartDaemon = "daemon_restart"
	FuseUpdate    = "agent_fusingrule_update"
	ConfUpdate    = "agent_config_update"
	PipePath      = ""

	ProxyNginxName = "proxy"
	LocalNginxName = "gateway"
	IsUseProxy     = false
	DataPort       = ""
	ConfigPort     = ""
	FilePort       = ""

	WorkPath = ""

	// 配置下发
	ConfigurateDistribute = "configuration_distribute"
	// 熔断下发
	FuseRuleDistribute = "fusingrule_distribute"

	// 任务操作
	CreateRunner = "collector_start"
	StopRunner   = "collector_stop"
	ReSetRunner  = "collector_reset"
	DeleteRunner = "collector_delete"

	// Daemon操作
	UpgradeDaemon   = "daemon_upgrade"
	UninstallDaemon = "daemon_uninstall"

	// 任务状态
	Running = "running"
	Success = "success"
	Fail    = "fail"
	InValid = "invalid"
)

// 状态编码
var (
	SuccessCode = 100000

	// agent 获取失败
	AgentGetErrorCode = 200000

	// agent 启动错误码
	AgentStartupErrorCode = 200001
	// agent 停止错误码
	AgentStopErrorCode = 200002
	// agent 重启错误码
	AgentRestartErrorCode = 200003
	// agent 卸载错误码
	AgentUninstallErrorCode = 200004
	// agent 安装失败
	AgentInstallErrorCode = 200005
	// agent 更新熔断规则失败
	AgentFuseUpdateErrorCode = 200006

	// agent 升级失败
	AgentUpgradeErrorCode = 200007

	// distribute configuration failed
	DistributeConfigErrorCode = 200008

	DistributeFuseErrorCode = 200009

	// agent任务失败
	RunnerErrorCode = 300001

	// daemon 升级失败
	DaemonUpgradeErrorCode = 400001

	// daemon 卸载失败
	DaemonDeleteErrorCode = 400002

	// daemon 卸载失败
	DaemonRestartErrorCode = 400003

	// 任务被丢弃
	FailExecByHighLevelTask = 500001

	// 任务无效
	InvaildTask = 500002
)

type RegisterHostReq struct {
	LicenseKey    string `json:"license_key"`
	HostId        int64  `json:"host_id"`
	HostIp        string `json:"host_ip"`
	HostName      string `json:"host_name"`
	HostNameAlias string `json:"host_name_alias"`
	HostType      int    `json:"host_type"`
	Version       string `json:"version"`
	SysVersion    string `json:"sys_version"`
	SystemUuid    string `json:"system_uuid"`
	Ebpf          bool   `json:"ebpf"`
	AgentType     int    `json:"agent_type"`
}

// RegisterHostResponse 注册主机响应结构
type RegisterHostResponse struct {
	AccountID int `json:"account_id"`
}

type RegisterAppReq struct {
	AppId       int64  `json:"appId"`
	AppName     string `json:"appName"`
	AccountId   int    `json:"accountId"`
	AgentId     int64  `json:"agentId"`
	Sn          string `json:"sn"`
	Sport       int    `json:"sport"`
	ServiceType string `json:"serviceType"`
	CodeType    int    `json:"codeType"`
	App_type    int    `json:"app_type"`
	HostId      int64  `json:"hostId"`
	AppLang     string `json:"app_lang"`
	Sys         string `json:"sys"`
	//AppNameAnalysis []map[string]string `json:"app_name_analysis"`
	//CwAppTransform  string              `json:"cw_app_transform"`
	//OrgCode         string              `json:"org_code"`
	//AppZone         *string             `json:"app_zone"`
}

func (r *RegisterAppReq) Print() {
	println(r.String())
}

func (r *RegisterAppReq) String() string {
	a, err := json.Marshal(r)
	if err != nil {
		return err.Error()
	}
	return string(a)
}

func (w *WhiteListReq) String() string {
	a, err := json.Marshal(w)
	if err != nil {
		return err.Error()
	}
	return string(a)
}

type WhiteListReq struct {
	HostId    int64 `json:"host_id"`
	AccountId int   `json:"account_id"`
	WhiteType int   `json:"white_type"`
}

type WhiteListResp struct {
	Code int       `json:"code"`
	Msg  string    `json:"msg"`
	Data WhiteData `json:"data"`
}

type WhiteSettingInfo struct {
	AppName string `json:"app_name"`
	//K8SNamespace    string `json:"k8s_namespace"`
	//K8SWorkLoadName string `json:"k8s_workLoadName"`
	Filters string `json:"filters"`
	//Type            string `json:"type"`
	//PodName         string `json:"pod_name"`
	ProcessKey string `json:"process_key"`
	//OpenStack       int    `json:"collect_stack"`
	//UpdateTime      int64  `json:"update_time"`

	WhiteStackSettingInfo WhiteStackSettingT
}

type WhiteStackSettingT struct {
	// from getCodeSetting
	OpenStack int
	WhiteList string
	BlackList string
}

type Appscope struct {
	Settings []WhiteSettingInfo `json:"settings"`
	Code     string             `json:"code"`
}

type WhiteData struct {
	Executable      []string   `json:"executable"`
	OneagentEnable  int        `json:"oneagent_enable"`
	LastUpdatedTime int        `json:"last_updated_time"`
	Appscope        []Appscope `json:"appscope"`
}

type WhiteDataV2 struct {
	SettingList     []WhiteSettingInfo `json:"appscope"`
	LastUpdatedTime int                `json:"last_updated_time"`
}

type ReportRequest struct {
	RegistRequest
	AgentID     string `json:"agent_id"`
	StateDetail struct {
		Msg string `json:"msg"`
	} `json:"statedetail"`
	State          string `json:"state"`
	ConnectionTest bool   `json:"_connection_test"`
}

// 注册请求数据结构
type RegistRequest struct {
	Pid                 int         `json:"agent_pid"`
	User                string      `json:"agent_run_user"`
	IP                  string      `json:"ip"`
	HostName            string      `json:"host_name"`
	DaemonInstanceID    string      `json:"daemon_instance_id"`
	ContentIdentity     string      `json:"contentIdentity"`
	DaemonVersion       string      `json:"daemon_version"`
	Os                  string      `json:"os"`
	OsVersion           string      `json:"os_version"`
	CPUCount            int         `json:"cpu_count"`
	Mem                 int64       `json:"mem"`
	Timestamp           int64       `json:"timestamp"`
	Agents              []AgentInfo `json:"agents"`
	Status              string      `json:"status"`
	Tags                string      `json:"tags"`
	TagNames            string      `json:"tagNames"`
	AgentID             string      `json:"agent_ids"`
	ConfigIds           string      `json:"config_ids"`
	IsTestingConnection bool        `json:"is_connection_test"`
	Parent              string      `json:"parent"`
	Connect             string      `json:"connect"`
	OperatingEnv        string      `json:"operatingEnv"`
	*K8SInfo                        // k8s，容器化

	SystemVersion string `json:"system_version"`

	// 新增安装配置项
	Identification      string `json:"identification"`
	ClusterId           string `json:"cluster_id"`
	ProxyLocalIp        string `json:"proxy_local_ip"`
	PluginInstallParams string `json:"plugin_install_params"`

	// 新增系统 uuid
	SystemUUID string `json:"system_uuid"`
	HostID     string `json:"host_id"`
}

// k8s，容器化
type K8SInfo struct {
	Host_type string `json:"host_type,omitempty"`
	Namespace string `json:"namespace"` // 命名空间
	// Cluster_name   string `json:"cluster_name"`
	Pod_name      string `json:"pod_name"`         // 容器组名称
	Pod_ip        string `json:"pod_ip"`           // 容器组ip
	Node_name     string `json:"node_name"`        // 节点名称
	Node_ip       string `json:"node_ip"`          // 节点ip
	Cluster_name  string `json:"k8s_cluster_name"` // 集群名称
	ImageName     string `json:"image_name"`       // 镜像名称
	ImageVersion  string `json:"image_version"`    // 镜像版本
	K8sModuleName string `json:"k8s_module_name"`  // k8s模块名称
}

type AgentInfo struct {
	IsNamePipe           bool                 `json:"pipe"`
	EnableDeepDiscover   bool                 `json:"enable_deep_discover"`
	Pid                  int                  `json:"pid"`
	ConfigPath           string               `json:"config"`
	User                 string               `json:"username"`
	Agent_instance_id    string               `json:"agent_instance_id"`
	Agent_id             string               `json:"agent_id"`
	Version              string               `json:"version"`
	Url                  string               `json:"url"`
	Collectors           []Collectors         `json:"collectors"`
	P_resource_occupancy []Resource_occupancy `json:"p_resource_occupancy"`
	Fusing               string               `json:"fusing"`
	FusingVersion        float64              `json:"fusing_rules_version"`
	Fusing_condition     Fusing_condition     `json:"fusing_condition"`
	// 注册时安装配置文件的ID
	ConfigId           string `json:"configId"`
	FusingId           string `json:"fusingId"`
	DepthDiscoverCycle string `json:"cdc_cycle"`
	Prefix             string `json:"prefix"` // cdc接口路由前缀
	// 日志路径字段
	LogPath string `json:"log_path"`

	// proxy 内网ip
	ProxyLocalIp string `json:"proxy_local_ip"`
}

type CodeSettingReq struct {
	AccountId int   `json:"accountId"`
	AgentId   int64 `json:"agentId"`
	Appid     int64 `json:"appId"`
	HostId    int64 `json:"hostId"`
}

type CodeSettingResp struct {
	BlackWhiteSettings struct {
		WhiteList      string `json:"white_list"`
		BlackList      string `json:"black_list"`
		BlackWhiteList int    `json:"black_white_list"`
		CollectStack   int    `json:"collect_stack"`
	} `json:"black_white_settings"`
}

type EbpfAppReq struct {
	AccountId int `json:"account_id"`
}

type EbpfAppResp map[string]string

type TaskStatus struct {
	TaskId     string `json:"taskid"`
	TaskStatus string `json:"taskStatus"`
}

type Collectors struct {
	Name            interface{}            `json:"name"`
	Status          string                 `json:"status"`
	CollectorConfig map[string]interface{} `json:"collectorConfig"`
	Id              string                 `json:"id"`
	Type            string                 `json:"type"`
}

// 资源使用
type Resource_occupancy struct {
	Pid int     `json:"pid"`
	Cpu float64 `json:"cpu"`
	Mem float32 `json:"mem"`
}

// agent熔断规则
type Fusing_condition struct {
	Cpu    int `json:"cpu"`
	Memory int `json:"memory"`
	Disk   int `json:"disk"`
}

// 结果解析
type RespJson struct {
	Code       int             `json:"code"`
	Msg        string          `json:"msg"`
	Status     string          `json:"status"`
	Encryption bool            `json:"encryption"`
	Data       json.RawMessage `json:"data"`
}

type RegistorRespData struct {
	Agents []AgentList `json:"agents"`
	Ip     string      `json:"realIp"`
	// server 当前时间戳
	ServerNow         int64              `json:"serverNow"`
	AgentInstallInfos []AgentInstallInfo `json:"agentInstallInfos"`
}

type AgentList struct {
	Agent_instance_id     string                 `json:"path"`
	Status                string                 `json:"status"`
	Collectors            []Collectors           `json:"collectors"`
	FusingRulesVersion    float64                `json:"fusing_rules_version"`
	Default_FusingContent map[string]interface{} `json:"default_FusingContent"`
}

type AgentInstallInfo struct {
	AgentId     string                 `json:"agentId"`
	InstallPath string                 `json:"installPath"`
	Config      map[string]interface{} `json:"config"`
	ConfigId    string                 `json:"configId"`
	FusingId    string                 `json:"fusingId"`
}

type HeartBeatInfo struct {
	Fusing               bool                 `json:"fusing"`
	Pid                  int                  `json:"agent_pid"`
	Status               int                  `json:"fuse_status"`
	FusingVersion        float64              `json:"fusing_rules_version"`
	AgentInstanceID      string               `json:"agent_instance_id"`
	ConfVersion          string               `json:"contentIdentity"`
	User                 string               `json:"agent_run_user"`
	P_resource_occupancy []map[string]float64 `json:"p_resource_occupancy"`
	Fusing_condition     map[string]float64   `json:"fusing_condition"`
}

type DaemonHeartBeatInfo struct {
	Status               int                  `json:"status"`
	Daemon_instance_id   string               `json:"daemon_instance_id"`
	ContentIdentity      string               `json:"contentIdentity"`
	P_resource_occupancy []map[string]float64 `json:"p_resource_occupancy"`
	HeartBeatInfo        []HeartBeatInfo      `json:"agents"`
	Timestamp            int64                `json:"timestamp"`
	Alive_agent          []string             `json:"agent_instance_ids"` // 离线agentid上报
}

type HeartConfContent struct {
	Content   string `json:"content"`
	ContentID string `json:"contentIdentity"`
}

type HeartJsonConf struct {
	Content   json.RawMessage `json:"content"`
	ContentID string          `json:"contentIdentity"`
}

type FuseContent struct {
	Content json.RawMessage `json:"fusing"`
}

type HB_Config struct {
	HB_Config_Detail map[string]HeartConfContent `json:"config"`
}

type Task struct {
	TaskId          string                 `json:"taskId"`
	Detail          Detail                 `json:"detail"`
	Status          string                 `json:"status"`
	TimeStamp       int64                  `json:"timestamp"`
	TaskConfig      map[string]interface{} `json:"taskConfig"`
	AgentInstanceId string                 `json:"agentPath"`
	Operate         string                 `json:"operate"`
}

func (t *Task) GetTaskConfigString(key string) (string, string) {
	err := ""
	v, ok := t.TaskConfig[key]
	if !ok {
		log.Errorf("task is %v Get value err, Can not get %s", t, key)
		err = fmt.Sprintf("task id is %s, Get value err, Can not get %s", t.TaskId, key)
		return "", err
	}
	result, ok := v.(string)
	if !ok {
		log.Errorf("task is %v Get value err, Value is not a string %v", t, v)
		err = fmt.Sprintf("task id is %s, Get value err, Value is not a string %v", t.TaskId, v)
		return "", err
	}
	return result, ""
}

func (t *Task) GetTaskConfigAny(key string) (interface{}, string) {
	err := ""
	v, ok := t.TaskConfig[key]
	if !ok {
		log.Warnf("task is %v Get value err, Can not get %s", t, key)
		err = fmt.Sprintf("task id is %s, Get value err, Can not get %s", t.TaskId, key)
		return nil, err
	}
	return v, ""
}

type Detail struct {
	Msg string `json:"msg"`
	AgentInfo
}

type TaskResult struct {
	Code      int    `json:"code"`
	Task_Id   string `json:"taskId"`
	Detail    Detail `json:"detail"`
	Status    string `json:"status"`
	TimeStamp int64  `json:"timestamp"`
}

// Agent心跳结果解析
type HeartBeatRespJson struct {
	Code string         `json:"code"`
	Data AgentHeartbeat `json:"data"`
}

type AgentHeartbeat struct {
	P_resource_occupancy []map[string]float64 `json:"p_resource_occupancy"`
	Fusing               bool                 `json:"fusing"`
	FusingVersion        float64              `json:"fusing_rules_version"`
	Fusing_condition     map[string]int       `json:"fusing_condition"`
	ConfVersion          string               `json:"contentIdentity"`
}

// 熔断功能对象创建
var (
	Pid    int
	CPUNUM float64
)

// 资源对象，包括资源限制名称、资源的阈值、阈值触发次数、阈值触发次数状态为熔断
type Rule struct {
	ThresholdTimes int     // 触发阈值的次数统计
	RecoverTimes   int     // 恢复次数统计
	Threshold      float64 // 阈值
	Enable         bool    // 是否启用
}

// 解析agent的数据结构
type Result struct {
	Timestamp int64              `json:"timestamp"`
	Pid       int                `json:"pid"`
	Command   string             `json:"command"`
	Class     string             `json:"type"`
	Metrics   map[string]float64 `json:"metric"`
}

// 熔断规则配置数据结构
type FuseConfig struct {
	TholdCount          int                `json:"tholdCount"`          // 多少次阈值触发熔断
	RecoveryCount       int                `json:"recoveryCount"`       // 多少次正常可以恢复agent的状态
	Window              int                `json:"monFrequency"`        // 多长时间采集一次agent的指标数据
	Version             int                `json:"version"`             // 熔断规则版本
	ShakeCountThreshold int                `json:"shakeCountThreshold"` // 抖动次数阈值
	Cycle               int                `json:"cycle"`               // 抖动触发周期
	Threshold           map[string]float64 `json:"threshold"`           // 熔断规则阈值
}
