// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package datetime_test

import (
	"encoding/json"
	"encoding/xml"
	"testing"
	"time"

	"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime"
	"github.com/stretchr/testify/require"
)

type timeInfoJSON struct {
	StartTime *datetime.RFC3339
}

type timeInfoXML struct {
	Expiry *datetime.RFC3339
}

func TestRFC3339(t *testing.T) {
	originalTime := time.Date(2023, time.June, 15, 14, 30, 45, 0, time.UTC)
	dt := datetime.RFC3339(originalTime)
	result := dt.String()
	require.NotEmpty(t, result)

	jsonBytes, err := dt.MarshalJSON()
	require.NoError(t, err)
	var dt2 datetime.RFC3339
	err = dt2.UnmarshalJSON(jsonBytes)
	require.NoError(t, err)
	require.Equal(t, originalTime, time.Time(dt2))

	textBytes, err := dt.MarshalText()
	require.NoError(t, err)
	var dt3 datetime.RFC3339
	err = dt3.UnmarshalText(textBytes)
	require.NoError(t, err)
	require.Equal(t, originalTime, time.Time(dt3))
}

func TestRFC3339_WithSpace_JSON(t *testing.T) {
	dst := timeInfoJSON{}
	require.NoError(t, json.Unmarshal([]byte(`{"startTime":"2024-01-18 14:18:54Z"}`), &dst))
	require.NotNil(t, dst.StartTime)
	require.WithinDuration(t, time.Date(2024, 1, 18, 14, 18, 54, 0, time.UTC), time.Time(*dst.StartTime), 0)

	dst = timeInfoJSON{}
	require.NoError(t, json.Unmarshal([]byte(`{"startTime":"2024-01-18 14:18:54.123Z"}`), &dst))
	require.NotNil(t, dst.StartTime)
	require.WithinDuration(t, time.Date(2024, 1, 18, 14, 18, 54, 123000000, time.UTC), time.Time(*dst.StartTime), 0)

	dst = timeInfoJSON{}
	require.NoError(t, json.Unmarshal([]byte(`{"startTime":"2024-01-18 14:18:54"}`), &dst))
	require.NotNil(t, dst.StartTime)
	require.WithinDuration(t, time.Date(2024, 1, 18, 14, 18, 54, 0, time.UTC), time.Time(*dst.StartTime), 0)

	dst = timeInfoJSON{}
	require.NoError(t, json.Unmarshal([]byte(`{"startTime":"2024-01-18 14:18:54.123"}`), &dst))
	require.NotNil(t, dst.StartTime)
	require.WithinDuration(t, time.Date(2024, 1, 18, 14, 18, 54, 123000000, time.UTC), time.Time(*dst.StartTime), 0)
}

func TestRFC3339_WithSpace_XML(t *testing.T) {
	dst := timeInfoXML{}
	require.NoError(t, xml.Unmarshal([]byte(`<timeInfo><Expiry>2024-01-18 14:18:54Z</Expiry></timeInfo>`), &dst))
	require.NotNil(t, dst.Expiry)
	require.WithinDuration(t, time.Date(2024, 1, 18, 14, 18, 54, 0, time.UTC), time.Time(*dst.Expiry), 0)

	dst = timeInfoXML{}
	require.NoError(t, xml.Unmarshal([]byte(`<timeInfo><Expiry>2024-01-18 14:18:54.123Z</Expiry></timeInfo>`), &dst))
	require.NotNil(t, dst.Expiry)
	require.WithinDuration(t, time.Date(2024, 1, 18, 14, 18, 54, 123000000, time.UTC), time.Time(*dst.Expiry), 0)

	dst = timeInfoXML{}
	require.NoError(t, xml.Unmarshal([]byte(`<timeInfo><Expiry>2024-01-18 14:18:54</Expiry></timeInfo>`), &dst))
	require.NotNil(t, dst.Expiry)
	require.WithinDuration(t, time.Date(2024, 1, 18, 14, 18, 54, 0, time.UTC), time.Time(*dst.Expiry), 0)

	dst = timeInfoXML{}
	require.NoError(t, xml.Unmarshal([]byte(`<timeInfo><Expiry>2024-01-18 14:18:54.123</Expiry></timeInfo>`), &dst))
	require.NotNil(t, dst.Expiry)
	require.WithinDuration(t, time.Date(2024, 1, 18, 14, 18, 54, 123000000, time.UTC), time.Time(*dst.Expiry), 0)
}

func TestRFC3339_empty(t *testing.T) {
	tt := datetime.RFC3339{}
	require.NoError(t, xml.Unmarshal([]byte("<RFC3339/>"), &tt))
	require.Zero(t, tt)
}
