package main

import (
	"context"
	"google.golang.org/grpc"
	client "iaun.cn/linux/services/client"
	"time"
)

func getCtx() (context.Context, context.CancelFunc) {
	return context.WithTimeout(context.Background(), 1*time.Second)
}

func newConn(addr string, ctx context.Context) (*grpc.ClientConn, error) {
	return grpc.DialContext(ctx, addr, grpc.WithBlock(), grpc.WithInsecure())
}

func newClient(conn *grpc.ClientConn) client.ClientClient {
	return client.NewClientClient(conn)
}

/*
	ctx, cancel := getCtx()
	defer cancel()
	conn, err := newConn(addr, ctx)
	if err != nil {
		return 0, err.Error()
	}
	defer func() { _ = conn.Close() }()
	c := newClient(conn)
*/

func sendInit(addr string, server *client.Server) (success int32, msg string) {
	cpus, err := getCPU()
	if err != nil {
		return 0, err.Error()
	}
	cpu := make([]*client.CPUInit, len(*cpus))
	for k, v := range *cpus {
		cpu[k] = new(client.CPUInit)
		cpu[k].Name = v.ModelName
		cpu[k].Count = v.Cores
		cpu[k].Mhz = v.Mhz
		cpu[k].CacheSize = v.CacheSize
	}
	ctx, cancel := getCtx()
	defer cancel()
	conn, err := newConn(addr, ctx)
	if err != nil {
		return 0, err.Error()
	}
	defer func() { _ = conn.Close() }()
	c := newClient(conn)
	ctx1, cancel1 := getCtx()
	defer cancel1()
	r, err := c.Init(ctx1, &client.InitReq{Server: server, CPU: cpu})
	if err != nil {
		return 0, err.Error()
	}
	return r.Success, r.Msg
}

func sendMemory(addr string, server *client.Server) (success int32, msg string) {
	mem, err := getMem()
	if err != nil {
		return 0, err.Error()
	}
	ctx, cancel := getCtx()
	defer cancel()
	conn, err := newConn(addr, ctx)
	if err != nil {
		return 0, err.Error()
	}
	defer func() { _ = conn.Close() }()
	c := newClient(conn)
	memInfo := new(client.MemoryReq)
	memInfo.Server = server
	memInfo.Total = mem.Total
	memInfo.Free = mem.Free
	memInfo.Used = mem.Used
	memInfo.Cached = mem.Cached
	memInfo.UsedPercent = mem.UsedPercent
	ctx1, cancel1 := getCtx()
	defer cancel1()
	r, err := c.Memory(ctx1, memInfo)
	if err != nil {
		return 0, err.Error()
	}
	return r.Success, r.Msg
}

func sendNetIO(addr string, server *client.Server) (success int32, msg string) {
	net, err := getNetIO()
	if err != nil {
		return 0, err.Error()
	}
	ctx, cancel := getCtx()
	defer cancel()
	conn, err := newConn(addr, ctx)
	if err != nil {
		return 0, err.Error()
	}
	defer func() { _ = conn.Close() }()
	c := newClient(conn)
	ctx1, cancel1 := getCtx()
	defer cancel1()
	netInfo := new(client.NetReq)
	netInfo.Server = server
	netInfo.BytesRecv = net.BytesRecv
	netInfo.BytesSent = net.BytesSent
	netInfo.PacketsRecv = net.PacketsRecv
	netInfo.PacketsSent = net.PacketsSent

	r, err := c.Network(ctx1, netInfo)
	if err != nil {
		return 0, err.Error()
	}
	return r.Success, r.Msg
}

func sendCPUPercent(addr string, server *client.Server) (success int32, msg string) {
	percent, err := getCPUPercent()
	if err != nil {
		return 0, err.Error()
	}
	req := new(client.CPUReq)
	req.Server = server
	req.Percent = percent
	ctx, cancel := getCtx()
	defer cancel()
	conn, err := newConn(addr, ctx)
	if err != nil {
		return 0, err.Error()
	}
	defer func() { _ = conn.Close() }()
	c := newClient(conn)
	ctx1, cancel1 := getCtx()
	defer cancel1()
	r, err := c.CPUPercent(ctx1, req)
	if err != nil {
		return 0, err.Error()
	}
	return r.Success, r.Msg
}

func sendDisk(addr string, server *client.Server) (success int32, msg string) {
	//TODO
	return 1, ""
}
