package cvt

import (
	"encoding/json"
	"fmt"

	jmpent "github.com/tidbcloud/devops/entity/jump"
	"github.com/tidbcloud/devops/models/base"
	jmpmod "github.com/tidbcloud/devops/models/jump"
	timeutil "github.com/tidbcloud/devops/pkg/infra/utils/time"
)

type e2m struct{}

func (cvt e2m) Authorization(e *jmpent.Authorization) *jmpmod.Authorization {
	m := &jmpmod.Authorization{
		Updatable: base.Updatable{
			Base: base.Base{ID: base.ID(e.ID)},
		},

		Privilege:           string(e.Privilege),
		Expiration:          string(e.Expiration),
		Reason:              e.Reason,
		Applicant:           e.Applicant,
		EnableGatewayAccess: e.EnableGatewayAccess,

		Phase:      string(e.Phase),
		ApprovalID: e.ApprovalID,
		ClosedAt:   timeutil.TsToTime(e.ClosedAt),
		ExpireAt:   timeutil.TsToTime(e.ExpireAt),
	}

	for _, j := range e.Jumps {
		m.Jumps = append(m.Jumps, cvt.Jump(j, e.ID))
	}

	return m
}

func (cvt e2m) Jump(e *jmpent.Jump, authID uint64) *jmpmod.Jump {
	jp := &jmpmod.Jump{
		ID:     base.ID(e.ID),
		Method: string(e.Method),

		AuthID: authID,
	}

	union, err := json.Marshal(e.Destination)
	if err != nil {
		panic(fmt.Errorf("failed to marshal destination union: %w", err))
	}
	jp.DestinationType = string(e.Destination.Extract().Type())
	jp.Destination = union
	jp.DestinationID = e.Destination.Extract().ID()

	attr, err := json.Marshal(e.Attributes)
	if err != nil {
		panic(fmt.Errorf("failed to marshal jump attributes: %w", err))
	}
	jp.Attributes = attr

	return jp
}
