package api

import (
	"agent/client/events"
	"agent/commons/utils"
	"context"
	"encoding/json"

	"github.com/google/uuid"
)

type ClientHandshake struct {
	ProjectName string `json:"project_name"`
	ProjectUuid UUID   `json:"project_uuid"`
	Uuid        UUID   `json:"uuid"`
	Name        string `json:"name"`
	Value       string `json:"value"`
	PrivKey     string `json:"priv_key"`
	PubKey      string `json:"pub_key"`
	CreatorUuid UUID   `json:"creator_uuid"`
	Created     int64  `json:"created"`
	Updated     int64  `json:"updated"`
}

func ClientHandshakeCreate(ctx context.Context, client IClient,
	args ClientHandshakeCreateArgs,
) (res ClientHandshake, err error) {
	event, err := EventClientHandshakeCreate(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientHandshakeDelete(ctx context.Context, client IClient,
	uuid uuid.UUID,
) error {
	event, err := EventClientHandshakeDelete(uuid)
	if err != nil {
		return err
	}
	_, err = events.ExecuteAndGetData(ctx, client, event)
	return err
}

func ClientHandshakeGet(ctx context.Context, client IClient,
	args ClientHandshakeGetArgs,
) (res ClientHandshake, err error) {
	event, err := EventClientHandshakeGet(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientHandshakeGetByUuidRaw(ctx context.Context, client IClient,
	uuid uuid.UUID,
) (res ClientHandshake, err error) {
	args := ClientHandshakeGetArgs{
		Uuid: UUID(uuid),
		Raw:  utils.PointerTo(true),
	}
	return ClientHandshakeGet(ctx, client, args)
}

func ClientHandshakeGetByUuid(ctx context.Context, client IClient,
	uuid uuid.UUID,
) (res ClientHandshake, err error) {
	args := ClientHandshakeGetArgs{
		Uuid: UUID(uuid),
		Raw:  utils.PointerTo(false),
	}
	return ClientHandshakeGet(ctx, client, args)
}

func ClientHandshakeGetByNameRaw(ctx context.Context, client IClient,
	projectUuid uuid.UUID, name string,
) (res ClientHandshake, err error) {
	args := ClientHandshakeGetArgs{
		ProjectUuid: UUID(projectUuid),
		Name:        name,
		Raw:         utils.PointerTo(true),
	}
	return ClientHandshakeGet(ctx, client, args)
}

func ClientHandshakeGetByName(ctx context.Context, client IClient,
	projectUuid uuid.UUID, name string,
) (res ClientHandshake, err error) {
	args := ClientHandshakeGetArgs{
		ProjectUuid: UUID(projectUuid),
		Name:        name,
		Raw:         utils.PointerTo(false),
	}
	return ClientHandshakeGet(ctx, client, args)
}

func ClientHandshakeGetByValueRaw(ctx context.Context, client IClient,
	projectUuid uuid.UUID, value string,
) (res ClientHandshake, err error) {
	args := ClientHandshakeGetArgs{
		ProjectUuid: UUID(projectUuid),
		Value:       value,
		Raw:         utils.PointerTo(true),
	}
	return ClientHandshakeGet(ctx, client, args)
}

func ClientHandshakeGetByValue(ctx context.Context, client IClient,
	projectUuid uuid.UUID, value string,
) (res ClientHandshake, err error) {
	args := ClientHandshakeGetArgs{
		ProjectUuid: UUID(projectUuid),
		Value:       value,
		Raw:         utils.PointerTo(false),
	}
	return ClientHandshakeGet(ctx, client, args)
}

func ClientHandshakeUpdate(ctx context.Context, client IClient,
	args ClientHandshakeUpdateArgs,
) (res ClientHandshake, err error) {
	event, err := EventClientHandshakeUpdate(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientHandshakeList(ctx context.Context, client IClient,
	args ClientHandshakeListArgs,
) (res []ClientHandshake, err error) {
	event, err := EventClientHandshakeList(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientHandshakeListByProject(ctx context.Context, client IClient,
	args ClientHandshakeListByProjectArgs,
) (res []ClientHandshake, err error) {
	event, err := EventClientHandshakeListByProject(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientHandshakeListAll(ctx context.Context, client IClient,
	args ...ClientHandshakeListAllArgs,
) (res []ClientHandshake, err error) {
	event, err := EventClientHandshakeListAll(args...)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}
