package common

import (
	"encoding/json"

	"github.com/fiskerinc/cloud-services/pkg/grpc/kafka_grpc"
	"github.com/pkg/errors"
)

type CANBusFrame struct {
	EpochUsec int64  `json:"epoch_usec"`
	ID        int    `json:"id"`
	Data      string `json:"data"`
}
type CANBusMessageRaw struct {
	EpochUsec int64         `json:"epoch_usec"`
	Dropped   int           `json:"dropped"`
	Filtered  int           `json:"filtered"`
	Frames    []CANBusFrame `json:"frames"`
}
type CarDataBatchPayloadRaw struct {
	Handler string           `json:"handler"`
	Data    CANBusMessageRaw `json:"data"`
	Version string           `json:"version"`
}

// CarDataBatchPayload is a payload received from T.Rex
//
//	it contains batches of CANMessages (can.go)
type CarDataBatchPayload struct {
	Handler string        `json:"handler"`
	Data    CANBusMessage `json:"data"`
	Version string        `json:"version"`
}

func (c *CarDataBatchPayload) Marshal() ([]byte, error) {
	data, err := json.Marshal(*c)
	return data, errors.WithStack(err)

}

func (c *CarDataBatchPayload) Unmarshal(data []byte) error {
	err := json.Unmarshal(data, c)
	return errors.WithStack(err)
}

func (c *CarDataBatchPayload) ToGrpc(data MessageRawJSON, vin string) (*kafka_grpc.GRPC_BatchPayload, error) {
	var payload CANBusMessageRaw
	err := json.Unmarshal(data.Data, &payload)
	if err != nil {
		return nil, errors.WithStack(err)
	}

	frames := make([]*kafka_grpc.GRPC_CANFrame, len(payload.Frames))
	msg := kafka_grpc.GRPC_CANData{
		EpochUsec: payload.EpochUsec,
		Dropped:   int32(payload.Dropped),
		Filtered:  int32(payload.Filtered),
		Frames:    frames,
		Vin:       vin,
	}

	for i, frame := range payload.Frames {
		msg.Frames[i] = &kafka_grpc.GRPC_CANFrame{
			Epoch: frame.EpochUsec,
			ID:    int32(frame.ID),
			Value: []byte(frame.Data),
		}
	}
	batch_payload := kafka_grpc.GRPC_BatchPayload{
		Handler: data.Handler,
		Data:    &msg,
		Version: data.Version,
	}
	return &batch_payload, nil
}
