package compute

import (
	"context"
	"encoding/json"
	"net/http"
	"strconv"

	"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)

// MigrateRequest struct to migrate compute
type MigrateRequest struct {
	// ID of compute instance
	// Required: true
	ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`

	// Particular Node ID to migrate this compute to
	// Required: false
	TargetNodeID uint64 `url:"targetNodeId,omitempty" json:"targetNodeId,omitempty"`
}

type AsyncWrapperMigrateRequest struct {
	MigrateRequest
	SyncMode bool `url:"sync"`
}

// Migrate migrates compute to another node
func (c Compute) Migrate(ctx context.Context, req MigrateRequest) (bool, error) {
	err := validators.ValidateRequest(req)
	if err != nil {
		return false, validators.ValidationErrors(validators.GetErrors(err))
	}

	url := "/cloudbroker/compute/migrate"

	syncReq := AsyncWrapperMigrateRequest{MigrateRequest: req, SyncMode: true}

	res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, syncReq)
	if err != nil {
		return false, err
	}

	result, err := strconv.ParseBool(string(res))
	if err != nil {
		return false, err
	}

	return result, nil
}

// AsyncMigrate migrates compute to another node in async mode
func (c Compute) AsyncMigrate(ctx context.Context, req MigrateRequest) (string, error) {
	err := validators.ValidateRequest(req)
	if err != nil {
		return "", validators.ValidationErrors(validators.GetErrors(err))
	}

	url := "/cloudbroker/compute/migrate"

	asyncReq := AsyncWrapperMigrateRequest{MigrateRequest: req, SyncMode: false}

	res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, asyncReq)
	if err != nil {
		return " ", err
	}

	var taskID string

	err = json.Unmarshal(res, &taskID)
	if err != nil {
		return "", err
	}

	return taskID, nil
}
