package flags

import (
	"encoding/json"
	"fmt"
	"io"
	"os"
	"path"
	"time"

	"github.com/coroot/coroot-node-agent/utils"
	"github.com/coroot/coroot-node-agent/utils/modelse"
	"github.com/jedib0t/go-pretty/v6/table"
)

func DumpTableFeatures(outputFormat string) {
	dumpPath := path.Join(utils.GetDefaultRuntimePath(), "memdump")
	fileName := path.Join(dumpPath, "app.snap")

	// 打开文件并获取文件信息
	file, err := os.Open(fileName)
	if err != nil {
		fmt.Println("no app.snap")
		os.Exit(0)
	}
	defer file.Close()

	// 获取文件修改时间
	fileInfo, err := file.Stat()
	if err != nil {
		fmt.Println("Failed to get file information")
		os.Exit(0)
	}
	fileModTime := fileInfo.ModTime().Format("2006/01/02 15:04:05")

	// 读取文件内容
	content, err := io.ReadAll(file)
	if err != nil {
		fmt.Println("Failed to read file content")
		os.Exit(0)
	}

	s := make(map[uint32]modelse.AppStatusInfo)
	err = json.Unmarshal(content, &s)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(0)
	}

	// 根据输出格式选择显示方式
	if outputFormat == "json" {
		// JSON格式输出
		output := map[string]interface{}{
			"snap_updated": fileModTime,
			"data":         s,
		}
		jsonData, err := json.MarshalIndent(output, "", "  ")
		if err != nil {
			fmt.Println("Failed to marshal JSON:", err.Error())
			os.Exit(1)
		}
		fmt.Println(string(jsonData))
	} else {
		// 默认表格格式输出
		t := table.NewWriter()
		t.SetTitle(fmt.Sprintf("Application Status (Snap Updated: %s)", fileModTime))

		for pid, info := range s {
			service := fmt.Sprintf("%s", info.Sn)
			t.AppendRow(table.Row{
				//info.AgentID,
				//info.UpdateAt,
				pid,
				info.ProcName,
				info.AppName,
				info.Container,
				info.Rule,
				info.Language,
				service,
				info.AppID,
				info.RegisterAt,
				info.PreStatus.String(),
				info.Status.String(),
				info.StackStatus,
			})
		}
		t.SetAutoIndex(true)
		t.AppendHeader(table.Row{
			//"agent id",
			//"update at",
			"pid",
			"process",
			"app name",
			"container",
			"app rule",
			"code",
			"service",
			"app id",
			"reg at",
			"app pre status",
			"app status",
			"stack status",
		})
		fmt.Println(t.Render())
	}
	os.Exit(0)
}

func DumpRuleTableFeatures(outputFormat string) {
	dumpPath := path.Join(utils.GetDefaultRuntimePath(), "memdump")
	fileName := path.Join(dumpPath, "rule.snap")

	// 打开文件并获取文件信息
	file, err := os.Open(fileName)
	if err != nil {
		fmt.Println("no rule.snap")
		os.Exit(0)
	}
	defer file.Close()

	// 获取文件修改时间
	fileInfo, err := file.Stat()
	if err != nil {
		fmt.Println("Failed to get file information")
		os.Exit(0)
	}
	fileModTime := fileInfo.ModTime().Format("2006/01/02 15:04:05")

	// 读取文件内容
	content, err := io.ReadAll(file)
	if err != nil {
		fmt.Println("Failed to read file content")
		os.Exit(0)
	}

	var whiteData modelse.WhiteDataV2
	err = json.Unmarshal(content, &whiteData)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(0)
	}

	// 根据输出格式选择显示方式
	if outputFormat == "json" {
		// JSON格式输出
		lastUpdatedTime := time.Unix(int64(whiteData.LastUpdatedTime), 0).Format("2006/01/02 15:04:05")
		output := map[string]interface{}{
			"rule_updated": lastUpdatedTime,
			"snap_updated": fileModTime,
			"data":         whiteData.SettingList,
		}
		jsonData, err := json.MarshalIndent(output, "", "  ")
		if err != nil {
			fmt.Println("Failed to marshal JSON:", err.Error())
			os.Exit(1)
		}
		fmt.Println(string(jsonData))
	} else {
		// 默认表格格式输出
		t := table.NewWriter()

		// 设置表格标题，包含规则更新时间和文件更新时间
		lastUpdatedTime := time.Unix(int64(whiteData.LastUpdatedTime), 0).Format("2006/01/02 15:04:05")
		t.SetTitle(fmt.Sprintf("Rule Configuration (Rule Updated: %s, Snap Updated: %s)", lastUpdatedTime, fileModTime))
		for _, setting := range whiteData.SettingList {
			t.AppendRow(table.Row{
				setting.AppName,
				setting.ProcessKey,
				setting.Filters,
				setting.WhiteStackSettingInfo.OpenStack,
				setting.WhiteStackSettingInfo.WhiteList,
				setting.WhiteStackSettingInfo.BlackList,
			})
		}
		t.SetAutoIndex(true)
		t.AppendHeader(table.Row{
			"App Name",
			"Setting rule",
			"Filters",
			"Stack Switch",
			"White List",
			"Black List",
		})
		fmt.Println(t.Render())
	}
	os.Exit(0)
}
