// report_test.go
package models

import (
	"crypto/md5"
	"encoding/hex"
	"strconv"
	"strings"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/tidbcloud/observability/o11ymetering/pkg/common/constants"
	"gorm.io/gorm"
)

func TestMonthlyStatisticReport_BuildID(t *testing.T) {
	// Create a MonthlyStatisticReport instance with test data.
	msr := MonthlyStatisticReport{
		Timestamp:     1678886400, // Example timestamp
		Vendor:        "AWS",
		Region:        "ap-northeast-1",
		Env:           constants.Prod,
		MeteringGroup: constants.DedicatedDataplane,
		Tenant:        "tenant-xyz",
		Category:      constants.Logs,
		SubCategory:   "access_logs",
		CloudService:  constants.SimpleStorageService,
		Cost:          123.45,
	}

	// Manually build the expected ID string.
	strs := []string{
		strconv.Itoa(int(msr.Timestamp)),
		msr.Vendor,
		msr.Region,
		string(msr.Category),
		msr.SubCategory,
		string(msr.CloudService),
		string(msr.Env),
		string(msr.MeteringGroup),
		msr.Tenant,
	}
	text := strings.Join(strs, "-")
	hash := md5.Sum([]byte(text))
	expectedID := hex.EncodeToString(hash[:])

	// Call the BuildID method and assert the ID is as expected.
	actualID := msr.BuildID()
	assert.Equal(t, expectedID, actualID, "BuildID should generate the correct MD5 hash for MonthlyStatisticReport")
	assert.Equal(t, expectedID, msr.ID, "BuildID should set the ID field of the struct")
}

func TestMonthlyStatisticReport_BeforeCreate(t *testing.T) {
	// Create a MonthlyStatisticReport instance with an empty ID.
	msr := MonthlyStatisticReport{
		ID:            "", // Ensure ID is empty for BeforeCreate to generate it
		Timestamp:     1678886400,
		Vendor:        "AWS",
		Region:        "ap-northeast-1",
		Env:           constants.Prod,
		MeteringGroup: constants.DedicatedDataplane,
		Tenant:        "tenant-xyz",
		Category:      constants.Logs,
		SubCategory:   "access_logs",
		CloudService:  constants.SimpleStorageService,
		Cost:          123.45,
	}

	// Call BeforeCreate.
	err := msr.BeforeCreate(&gorm.DB{})
	assert.NoError(t, err, "BeforeCreate should not return an error")
	assert.NotEmpty(t, msr.ID, "BeforeCreate should generate an ID if it's empty")

	// Test case where ID is already set.
	originalID := "existing-report-id"
	msrWithID := MonthlyStatisticReport{
		ID:            originalID,
		Timestamp:     1678886400,
		Vendor:        "AWS",
		Region:        "ap-northeast-1",
		Env:           constants.Prod,
		MeteringGroup: constants.DedicatedDataplane,
		Tenant:        "tenant-xyz",
	}
	err = msrWithID.BeforeCreate(&gorm.DB{})
	assert.NoError(t, err, "BeforeCreate should not return an error when ID is already set")
	assert.Equal(t, originalID, msrWithID.ID, "BeforeCreate should not change the ID if it's already set")
}
