

package pb

import (
	"context"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

type RegisterRequest struct {
	ServerId    string `json:"server_id"`
	PreRegToken string `json:"pre_reg_token"`
	Hostname    string `json:"hostname"`
	IpAddress   string `json:"ip_address"`
	OsInfo      string `json:"os_info"`
}

type RegisterResponse struct {
	AgentToken string `json:"agent_token"`
}

type SyncRequest struct {
	ServerId     string `json:"server_id"`
	AgentToken   string `json:"agent_token"`
	AgentVersion string `json:"agent_version,omitempty"`
}

type SyncResponse struct {
	PublicKeys []string `json:"public_keys"`
}

type UploadKeyRequest struct {
	ServerId   string `json:"server_id"`
	AgentToken string `json:"agent_token"`
	PublicKey  string `json:"public_key"`
	Label      string `json:"label"`
	PrivateKey string `json:"private_key,omitempty"`
}

type UploadKeyResponse struct {
	KeyId string `json:"key_id"`
}



type PackageUpdate struct {
	Name           string `json:"name"`
	CurrentVersion string `json:"current_version,omitempty"`
	NewVersion     string `json:"new_version"`
}

type ReportUpdatesRequest struct {
	ServerId   string          `json:"server_id"`
	AgentToken string          `json:"agent_token"`
	Updates    []PackageUpdate `json:"updates"`
}

type ReportUpdatesResponse struct{}



type CPUReport struct {
	Model    string  `json:"model,omitempty"`
	Cores    int     `json:"cores,omitempty"`
	UsagePct float64 `json:"usage_pct"`
	Load1    float64 `json:"load1,omitempty"`
}
type MemReport struct {
	TotalBytes uint64 `json:"total_bytes"`
	UsedBytes  uint64 `json:"used_bytes"`
}
type PartitionReport struct {
	Device     string `json:"device"`
	Mountpoint string `json:"mountpoint"`
	Fstype     string `json:"fstype,omitempty"`
	TotalBytes uint64 `json:"total_bytes"`
	UsedBytes  uint64 `json:"used_bytes"`
}
type InventoryReport struct {
	ServerId      string            `json:"server_id"`
	AgentToken    string            `json:"agent_token"`
	IncludeStatic bool              `json:"include_static"`
	CPU           *CPUReport        `json:"cpu,omitempty"`
	Memory        *MemReport        `json:"memory,omitempty"`
	SwapTotal     uint64            `json:"swap_total"`
	SwapUsed      uint64            `json:"swap_used"`
	Partitions    []PartitionReport `json:"partitions,omitempty"`
	Kernel        string            `json:"kernel,omitempty"`
}
type InventoryReportResponse struct{}



type MonitorSpec struct {
	MonitorId      string `json:"monitor_id"`
	Type           string `json:"type"`
	URL            string `json:"url,omitempty"`
	Host           string `json:"host,omitempty"`
	Port           int    `json:"port,omitempty"`
	Method         string `json:"method,omitempty"`
	ExpectedStatus int    `json:"expected_status,omitempty"`
	Keyword        string `json:"keyword,omitempty"`
	TLSWarnDays    int    `json:"tls_warn_days,omitempty"`
	Insecure       bool   `json:"insecure,omitempty"`
	IntervalSec    int    `json:"interval_sec"`
	Retries        int    `json:"retries"`
}
type SyncMonitorsRequest struct {
	ServerId   string `json:"server_id"`
	AgentToken string `json:"agent_token"`
}
type SyncMonitorsResponse struct {
	Monitors []MonitorSpec `json:"monitors,omitempty"`
}
type CheckResult struct {
	MonitorId      string `json:"monitor_id"`
	Up             bool   `json:"up"`
	LatencyMs      int    `json:"latency_ms"`
	Message        string `json:"message,omitempty"`
	CertExpiryUnix int64  `json:"cert_expiry_unix,omitempty"`
}
type ReportChecksRequest struct {
	ServerId   string        `json:"server_id"`
	AgentToken string        `json:"agent_token"`
	Results    []CheckResult `json:"results,omitempty"`
}
type ReportChecksResponse struct{}

type ApplyUpdatesCmd struct{}

type ServerCommand struct {
	CommandId        string               `json:"command_id"`
	GenerateKey      *GenerateKeyCmd      `json:"generate_key,omitempty"`
	DeleteKey        *DeleteKeyCmd        `json:"delete_key,omitempty"`
	UpdateAgent      *UpdateAgentCmd      `json:"update_agent,omitempty"`
	ApplyUpdates     *ApplyUpdatesCmd     `json:"apply_updates,omitempty"`
	RunStep          *RunStepCmd          `json:"run_step,omitempty"`
	CleanupWorkspace *CleanupWorkspaceCmd `json:"cleanup_workspace,omitempty"`
}



type CleanupWorkspaceCmd struct {
	WorkspaceId string `json:"workspace_id"`
}

type DeleteKeyCmd struct {
	Label string `json:"label"`
}

type UpdateAgentCmd struct {
	Version      string `json:"version"`
	GiteaBaseURL string `json:"gitea_base_url"`
}

type GenerateKeyCmd struct {
	Label      string `json:"label"`
	KeyType    string `json:"key_type,omitempty"`
	KeySize    int    `json:"key_size,omitempty"`
	Passphrase string `json:"passphrase,omitempty"`
	Comment    string `json:"comment,omitempty"`
}

type AgentMessage struct {
	ServerId   string            `json:"server_id"`
	AgentToken string            `json:"agent_token"`
	Ready      *AgentReady       `json:"ready,omitempty"`
	Result     *CommandResult    `json:"result,omitempty"`
	StepResult *StepResult       `json:"step_result,omitempty"`
	StepOutput *StepOutputChunk  `json:"step_output,omitempty"`
}

type AgentReady struct{}

type CommandResult struct {
	CommandId string `json:"command_id"`
	Success   bool   `json:"success"`
	Message   string `json:"message"`
}

type RunStepCmd struct {
	Interpreter    string            `json:"interpreter"`
	Script         string            `json:"script"`
	Env            map[string]string `json:"env,omitempty"`
	TimeoutSeconds int               `json:"timeout_seconds,omitempty"`
	
	
	WorkspaceId string `json:"workspace_id,omitempty"`
}

type StepResult struct {
	CommandId string            `json:"command_id"`
	ExitCode  int               `json:"exit_code"`
	Stdout    string            `json:"stdout,omitempty"`
	Stderr    string            `json:"stderr,omitempty"`
	OutputEnv map[string]string `json:"output_env,omitempty"`
}

type StepOutputChunk struct {
	CommandId string `json:"command_id"`
	Seq       uint64 `json:"seq"`
	Data      []byte `json:"data,omitempty"`
	Eof       bool   `json:"eof,omitempty"`
}



type Vantage_CommandStreamClient interface {
	Send(*AgentMessage) error
	Recv() (*ServerCommand, error)
	grpc.ClientStream
}

type vantageCommandStreamClient struct {
	grpc.ClientStream
}

func (c *vantageCommandStreamClient) Send(m *AgentMessage) error {
	return c.ClientStream.SendMsg(m)
}

func (c *vantageCommandStreamClient) Recv() (*ServerCommand, error) {
	m := new(ServerCommand)
	if err := c.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}



type Vantage_CommandStreamServer interface {
	Send(*ServerCommand) error
	Recv() (*AgentMessage, error)
	grpc.ServerStream
}

type keyManagerCommandStreamServer struct {
	grpc.ServerStream
}

func (s *keyManagerCommandStreamServer) Send(m *ServerCommand) error {
	return s.ServerStream.SendMsg(m)
}

func (s *keyManagerCommandStreamServer) Recv() (*AgentMessage, error) {
	m := new(AgentMessage)
	if err := s.ServerStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

type VantageClient interface {
	Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterResponse, error)
	SyncKeys(ctx context.Context, in *SyncRequest, opts ...grpc.CallOption) (*SyncResponse, error)
	UploadGeneratedKey(ctx context.Context, in *UploadKeyRequest, opts ...grpc.CallOption) (*UploadKeyResponse, error)
	ReportUpdates(ctx context.Context, in *ReportUpdatesRequest, opts ...grpc.CallOption) (*ReportUpdatesResponse, error)
	ReportInventory(ctx context.Context, in *InventoryReport, opts ...grpc.CallOption) (*InventoryReportResponse, error)
	SyncMonitors(ctx context.Context, in *SyncMonitorsRequest, opts ...grpc.CallOption) (*SyncMonitorsResponse, error)
	ReportChecks(ctx context.Context, in *ReportChecksRequest, opts ...grpc.CallOption) (*ReportChecksResponse, error)
	CommandStream(ctx context.Context, opts ...grpc.CallOption) (Vantage_CommandStreamClient, error)
}

type UnimplementedVantageServer struct{}

func (UnimplementedVantageServer) Register(context.Context, *RegisterRequest) (*RegisterResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "not implemented")
}
func (UnimplementedVantageServer) SyncKeys(context.Context, *SyncRequest) (*SyncResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "not implemented")
}
func (UnimplementedVantageServer) UploadGeneratedKey(context.Context, *UploadKeyRequest) (*UploadKeyResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "not implemented")
}

type keyManagerClient struct {
	cc grpc.ClientConnInterface
}

func NewVantageClient(cc grpc.ClientConnInterface) VantageClient {
	return &keyManagerClient{cc}
}

func (c *keyManagerClient) Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterResponse, error) {
	out := new(RegisterResponse)
	if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/Register", in, out, opts...); err != nil {
		return nil, err
	}
	return out, nil
}

func (c *keyManagerClient) SyncKeys(ctx context.Context, in *SyncRequest, opts ...grpc.CallOption) (*SyncResponse, error) {
	out := new(SyncResponse)
	if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/SyncKeys", in, out, opts...); err != nil {
		return nil, err
	}
	return out, nil
}

func (c *keyManagerClient) UploadGeneratedKey(ctx context.Context, in *UploadKeyRequest, opts ...grpc.CallOption) (*UploadKeyResponse, error) {
	out := new(UploadKeyResponse)
	if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/UploadGeneratedKey", in, out, opts...); err != nil {
		return nil, err
	}
	return out, nil
}

func (c *keyManagerClient) ReportUpdates(ctx context.Context, in *ReportUpdatesRequest, opts ...grpc.CallOption) (*ReportUpdatesResponse, error) {
	out := new(ReportUpdatesResponse)
	if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/ReportUpdates", in, out, opts...); err != nil {
		return nil, err
	}
	return out, nil
}

func (c *keyManagerClient) ReportInventory(ctx context.Context, in *InventoryReport, opts ...grpc.CallOption) (*InventoryReportResponse, error) {
	out := new(InventoryReportResponse)
	if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/ReportInventory", in, out, opts...); err != nil {
		return nil, err
	}
	return out, nil
}

func (c *keyManagerClient) SyncMonitors(ctx context.Context, in *SyncMonitorsRequest, opts ...grpc.CallOption) (*SyncMonitorsResponse, error) {
	out := new(SyncMonitorsResponse)
	if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/SyncMonitors", in, out, opts...); err != nil {
		return nil, err
	}
	return out, nil
}

func (c *keyManagerClient) ReportChecks(ctx context.Context, in *ReportChecksRequest, opts ...grpc.CallOption) (*ReportChecksResponse, error) {
	out := new(ReportChecksResponse)
	if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/ReportChecks", in, out, opts...); err != nil {
		return nil, err
	}
	return out, nil
}

func (c *keyManagerClient) CommandStream(ctx context.Context, opts ...grpc.CallOption) (Vantage_CommandStreamClient, error) {
	desc := &grpc.StreamDesc{StreamName: "CommandStream", ServerStreams: true, ClientStreams: true}
	stream, err := c.cc.NewStream(ctx, desc, "/vantage.v1.Vantage/CommandStream", opts...)
	if err != nil {
		return nil, err
	}
	return &vantageCommandStreamClient{stream}, nil
}
