package cvt

import (
	"encoding/json"
	"sort"
	"time"

	opent "github.com/tidbcloud/devops/entity/operation"
	opmod "github.com/tidbcloud/devops/models/operation"
)

type m2e struct{}

func (cvt m2e) Instance(m *opmod.OperationInstance) *opent.Instance {
	e := &opent.Instance{
		ID:             m.ID.Uint64(),
		Type:           opent.OperationTarget(m.Type),
		Operation:      m.Operation,
		Reason:         m.Reason,
		Applicant:      m.Applicant,
		OperatorEntity: m.OperatorEntity,

		ExecutionWindowID: m.ExecutionWindowID,

		Phase:      opent.InstancePhase(m.Phase),
		ApprovalID: m.ApprovalID,
		CreatedAt:  m.CreatedAt.Unix(),
		ClosedAt:   cvtTimeToTs(m.ClosedAt),
	}

	if m.Params != nil {
		params := map[opent.ParamName]string{}
		if err := json.Unmarshal(m.Params, &params); err != nil {
			panic(err)
		}
		e.Params = params
	}

	if m.Outputs != nil {
		outputs := map[opent.OutputName]string{}
		if err := json.Unmarshal(m.Outputs, &outputs); err != nil {
			panic(err)
		}
		e.Outputs = outputs
	}

	for _, action := range m.Actions {
		e.Actions = append(e.Actions, cvt.InstanceAction(action))
	}
	sort.Slice(e.Actions, func(i, j int) bool {
		return e.Actions[i].Order < e.Actions[j].Order
	})

	return e
}

func (cvt m2e) InstanceAction(m *opmod.OperationInstanceAction) *opent.InstanceAction {
	e := &opent.InstanceAction{
		ID: m.ID.Uint64(),

		Order:           opent.ActionOrder(m.Order),
		Name:            opent.ActionName(m.Name),
		Type:            opent.ActionType(m.Type),
		StartPolicy:     opent.ActionStartPolicy(m.StartPolicy),
		StartScheduleAt: cvtTimeToTs(m.StartScheduleAt),

		StartedAt:  cvtTimeToTs(m.StartedAt),
		FinishedAt: cvtTimeToTs(m.FinishedAt),
		Status:     opent.ActionStatus(m.Status),
		Output:     m.Output,
	}

	return e
}

func cvtTimeToTs(t *time.Time) *int64 {
	if t == nil {
		return nil
	}
	ts := t.Unix()
	return &ts
}
