package controllers

import (
	"encoding/json"

	oclib "cloud.o-forge.io/core/oc-lib"
	"cloud.o-forge.io/core/oc-lib/dbs"
	"cloud.o-forge.io/core/oc-lib/models/workflow_execution"
	"cloud.o-forge.io/core/oc-lib/tools"
	beego "github.com/beego/beego/v2/server/web"
	"github.com/google/uuid"
)

var orderCollection = oclib.LibDataEnum(oclib.ORDER)

// Operations about workflow
type WorkflowSchedulerController struct {
	beego.Controller
}

// @Title Schedule
// @Description schedule workflow
// @Param	id		path 	string	true		"id execution"
// @Param	body		body 	models.compute	true		"The compute content"
// @Success 200 {workspace} models.workspace
// @router /:id [post]
func (o *WorkflowSchedulerController) Schedule() {
	code := 200
	e := ""
	user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
	id := o.Ctx.Input.Param(":id")
	var resp *workflow_execution.WorkflowSchedule
	json.Unmarshal(o.Ctx.Input.CopyBody(100000), &resp)
	caller := tools.NewHTTPCaller(map[tools.DataType]map[tools.METHOD]string{ // paths to call other OC services
		tools.PEER: {
			tools.POST: "/status/",
		},
		tools.BOOKING: {
			tools.GET:  "/booking/check/:id/:start_date/:end_date",
			tools.POST: "/booking/",
		},
	})
	req := oclib.NewRequest(collection, user, peerID, groups, caller)
	resp.UUID = uuid.New().String()
	sch, err := req.Schedule(id, resp)
	if err != nil {
		if sch != nil {
			for _, w := range sch.WorkflowExecution {
				req.DeleteOne(w.GetID())
			}
		}
		o.Data["json"] = map[string]interface{}{
			"data":  nil,
			"code":  409,
			"error": err.Error(),
		}
		o.ServeJSON()
		return
	}
	o.Data["json"] = map[string]interface{}{
		"data":  sch.WorkflowExecution,
		"code":  code,
		"error": e,
	}
	o.ServeJSON()
}

// @Title UnSchedule
// @Description schedule workflow
// @Param	id		path 	string	true		"id execution"
// @Param	body		body 	models.compute	true		"The compute content"
// @Success 200 {workspace} models.workspace
// @router /:id [delete]
func (o *WorkflowSchedulerController) UnSchedule() {
	user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
	id := o.Ctx.Input.Param(":id")
	// TODO UNSCHEDULER
	filter := &dbs.Filters{
		And: map[string][]dbs.Filter{
			"workflow_id": {{Operator: dbs.EQUAL.String(), Value: id}},
		},
	}
	o.Data["json"] = oclib.NewRequest(collection, user, peerID, groups, nil).Search(filter, "", true)
	o.ServeJSON()
}

// @Title SearchScheduledDraftOrder
// @Description schedule workflow
// @Param	id		path 	string	true		"id execution"
// @Success 200 {workspace} models.workspace
// @router /:id/order [get]
func (o *WorkflowSchedulerController) SearchScheduledDraftOrder() {
	user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
	id := o.Ctx.Input.Param(":id")
	filter := &dbs.Filters{
		And: map[string][]dbs.Filter{
			"workflow_id": {{Operator: dbs.EQUAL.String(), Value: id}},
			"order_by":    {{Operator: dbs.EQUAL.String(), Value: peerID}},
		},
	}
	o.Data["json"] = oclib.NewRequest(orderCollection, user, peerID, groups, nil).Search(filter, "", true)
	o.ServeJSON()
}