package cvt

import (
	"encoding/json"
	"fmt"

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

type m2e struct{}

func (cvt m2e) Authorization(m *jmpmod.Authorization) *jmpent.Authorization {
	e := &jmpent.Authorization{
		ID:                  m.ID.Uint64(),
		Privilege:           jmpent.JumpPrivilege(m.Privilege),
		Expiration:          jmpent.JumpExpiration(m.Expiration),
		Reason:              m.Reason,
		Applicant:           m.Applicant,
		EnableGatewayAccess: m.EnableGatewayAccess,

		Phase:      jmpent.AuthorizationPhase(m.Phase),
		ApprovalID: m.ApprovalID,
		CreatedAt:  m.CreatedAt.Unix(),
		ClosedAt:   timeutil.TimeToTs(m.ClosedAt),
		ExpireAt:   timeutil.TimeToTs(m.ExpireAt),
	}

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

	return e
}

func (cvt m2e) Jump(m *jmpmod.Jump) *jmpent.Jump {
	jp := &jmpent.Jump{
		ID:     m.ID.Uint64(),
		Method: jmpent.JumpMethod(m.Method),
	}

	union := &jmpent.DestinationUnion{}
	err := json.Unmarshal(m.Destination, union)
	if err != nil {
		panic(fmt.Errorf("failed to unmarshal destination union: %w", err))
	}
	jp.DestinationType = union.Extract().Type()
	jp.Destination = union

	attr := &jmpent.JumpAttributes{}
	if m.Attributes != nil {
		err = json.Unmarshal(m.Attributes, attr)
		if err != nil {
			panic(fmt.Errorf("failed to unmarshal jump attributes: %w", err))
		}
	}
	jp.Attributes = *attr

	return jp
}
