package api

import (
	"agent/client/events"
	"agent/commons/utils"
	"agent/defines/devent/daction"
	"agent/defines/devent/dcategory"
	"agent/defines/devent/dkind"
)

type ConsoleCommandStatus int

var (
	ConsoleCommandNone      ConsoleCommandStatus = 0
	ConsoleCommandNew       ConsoleCommandStatus = 1
	ConsoleCommandReceived  ConsoleCommandStatus = 2
	ConsoleCommandError     ConsoleCommandStatus = 3
	ConsoleCommandCompleted ConsoleCommandStatus = 5
	ConsoleCommandExpired   ConsoleCommandStatus = 10
)

type ConsoleType int

var (
	ConsoleTypeNone    ConsoleType = 0
	ConsoleTypePublic  ConsoleType = 1
	ConsoleTypePrivate ConsoleType = 3
)

type ConsoleNewArgs struct {
	AgentUuid UUID `json:"agent_uuid"`
	TokenUuid UUID `json:"token_uuid,omitempty"`

	Uuid UUID        `json:"console_uuid,omitempty"`
	Name string      `json:"console_name"`
	Tag  string      `json:"console_tag,omitempty"`
	Type ConsoleType `json:"console_type"`

	Interval int    `json:"interval,omitempty"`
	Env      string `json:"env,omitempty"`
	Cwd      string `json:"cwd,omitempty"`
}

func EventConsoleNew(args ConsoleNewArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console},
		daction.New,
		meta,
	), nil
}

type ConsoleGetArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`
}

func EventConsoleGet(args ConsoleGetArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console, dcategory.Info},
		daction.Get,
		meta,
	), nil
}

func EventConsoleGetByUuid(uuid UUID) (IEvent, error) {
	args := ConsoleGetArgs{
		Uuid: uuid,
	}
	return EventConsoleGet(args)
}

func EventConsoleGetByName(agentUuid UUID, name string) (IEvent, error) {
	args := ConsoleGetArgs{
		AgentUuid: agentUuid,
		Name:      name,
	}
	return EventConsoleGet(args)
}

func EventConsoleGetByTag(agentUuid UUID, tag string) (IEvent, error) {
	args := ConsoleGetArgs{
		AgentUuid: agentUuid,
		Tag:       tag,
	}
	return EventConsoleGet(args)
}

func EventConsoleGetList(agentUuid UUID) (IEvent, error) {
	meta := map[string]any{
		"agent_uuid": agentUuid,
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console},
		daction.List,
		meta,
	), nil
}

type ConsoleSetTypeArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`

	Type ConsoleType `json:"console_type"`
}

func EventConsoleSetType(args ConsoleSetTypeArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console, dcategory.Type},
		daction.Set,
		meta,
	), nil
}

type ConsoleSetIntervalArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`

	Interval int `json:"interval"`
}

func EventConsoleSetInterval(args ConsoleSetIntervalArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console, dcategory.Interval},
		daction.Set,
		meta,
	), nil
}

type ConsolePinToArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`

	TokenUuid UUID `json:"token_uuid"`
}

func EventConsolePinTo(args ConsolePinToArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console},
		daction.Pin,
		meta,
	), nil
}

type ConsoleLockArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`
}

func EventConsoleLock(args ConsoleLockArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console},
		daction.Lock,
		meta,
	), nil
}

type ConsoleUnlockArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`
}

func EventConsoleUnlock(args ConsoleUnlockArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console},
		daction.Unlock,
		meta,
	), nil
}

type ConsoleOpenArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`
}

func EventConsoleOpen(args ConsoleOpenArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console},
		daction.Open,
		meta,
	), nil
}

type ConsoleCloseArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`
}

func EventConsoleClose(args ConsoleCloseArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console},
		daction.Close,
		meta,
	), nil
}

type ConsoleDeleteArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`
}

func EventConsoleDelete(args ConsoleDeleteArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console},
		daction.Delete,
		meta,
	), nil
}

type ConsoleGetOutputArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`

	LastId  int64 `json:"last_id,omitempty"`
	Offset  int64 `json:"offset,omitempty"`
	Limit   int64 `json:"limit,omitempty"`
	Reverse bool  `json:"reverse,omitempty"`
}

func EventConsoleGetOutput(args ConsoleGetOutputArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console, dcategory.Output},
		daction.Get,
		meta,
	), nil
}

type ConsoleSendInputArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`

	CommandUuid UUID   `json:"command_uuid,omitempty"`
	Command     string `json:"command"`
}

func EventConsoleSendInput(args ConsoleSendInputArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console, dcategory.Input},
		daction.Set,
		meta,
	), nil
}

type ConsoleGetInputOperatorArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`

	LastId  *int64 `json:"last_id,omitempty"`
	Offset  int64  `json:"offset,omitempty"`
	Limit   int64  `json:"limit,omitempty"`
	Reverse bool   `json:"reverse,omitempty"`
	Owner   *bool  `json:"owner,omitempty"`
}

func EventConsoleGetInputOperator(args ConsoleGetInputOperatorArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console, dcategory.Input},
		daction.Get,
		meta,
	), nil
}

type PrivateConsoleAddUserArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`

	UserUuids []UUID          `json:"user_uuid_list"`
	Rights    map[string]bool `json:"rights,omitempty"`
}

func EventPrivateConsoleAddUser(args PrivateConsoleAddUserArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console, dcategory.Right, dcategory.User},
		daction.Add,
		meta,
	), nil
}

type PrivateConsoleDeleteUserArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`

	UserUuids []UUID `json:"user_uuid_list"`
}

func EventPrivateConsoleDeleteUser(args PrivateConsoleDeleteUserArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console, dcategory.Right, dcategory.User},
		daction.Delete,
		meta,
	), nil
}

type PrivateConsoleGetUserArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`

	UserUuid UUID `json:"user_uuid"`
}

func EventPrivateConsoleGetUser(args PrivateConsoleGetUserArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console, dcategory.Right, dcategory.User},
		daction.Get,
		meta,
	), nil
}

type PrivateConsoleListUsersArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`
}

func EventPrivateConsoleListUsers(args PrivateConsoleListUsersArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console, dcategory.Right, dcategory.User},
		daction.List,
		meta,
	), nil
}

type PrivateConsoleUpdateUserArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`

	UserUuid UUID            `json:"user_uuid"`
	Rights   map[string]bool `json:"rights,omitempty"`
}

func EventPrivateConsoleUpdateUser(args PrivateConsoleUpdateUserArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console, dcategory.Right, dcategory.User},
		daction.Update,
		meta,
	), nil
}

type PrivateConsoleAddUserGroupArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`

	UserGroupUuids []UUID          `json:"user_group_uuid_list"`
	Rights         map[string]bool `json:"rights,omitempty"`
}

func EventPrivateConsoleAddUserGroup(args PrivateConsoleAddUserGroupArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console, dcategory.Right, dcategory.UserGroup},
		daction.Add,
		meta,
	), nil
}

type PrivateConsoleDeleteUserGroupArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`

	UserGroupUuids []UUID `json:"user_group_uuid_list"`
}

func EventPrivateConsoleDeleteUserGroup(args PrivateConsoleDeleteUserGroupArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console, dcategory.Right, dcategory.UserGroup},
		daction.Delete,
		meta,
	), nil
}

type PrivateConsoleGetUserGroupArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`

	UserGroupUuid UUID `json:"user_group_uuid"`
}

func EventPrivateConsoleGetUserGroup(args PrivateConsoleGetUserGroupArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console, dcategory.Right, dcategory.UserGroup},
		daction.Get,
		meta,
	), nil
}

type PrivateConsoleListUserGroupsArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`
}

func EventPrivateConsoleListUserGroups(args PrivateConsoleListUserGroupsArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console, dcategory.Right, dcategory.UserGroup},
		daction.List,
		meta,
	), nil
}

type PrivateConsoleUpdateUserGroupArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Uuid      UUID   `json:"console_uuid,omitempty"`
	Name      string `json:"console_name,omitempty"`
	Tag       string `json:"console_tag,omitempty"`

	UserGroupUuid UUID            `json:"user_group_uuid"`
	Rights        map[string]bool `json:"rights,omitempty"`
}

func EventPrivateConsoleUpdateUserGroup(args PrivateConsoleUpdateUserGroupArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Agent, dcategory.Console, dcategory.Right, dcategory.UserGroup},
		daction.Update,
		meta,
	), nil
}
