package field

import (
	"context"
	"reflect"
	"testing"

	"github.com/stretchr/testify/require"
)

func TestTimestamp_Decode(t *testing.T) {
	tests := []struct {
		name    string
		field   *Field
		data    interface{}
		want    interface{}
		wantErr bool
		errMsg  string
	}{
		{"Correct", Timestamp(), int64(2), int64(2), false, ""},                 // #0
		{"Correct", Timestamp(), int32(2), int64(2), false, ""},                 // #1
		{"Correct", Timestamp(), 2, int64(2), false, ""},                        // #2
		{"Correct", Timestamp(), "13h10m44s", int64(47444000000000), false, ""}, // #3
		{"Correct", Timestamp(), "24h", int64(86400000000000), false, ""},       // #4
		{"Correct", Timestamp(), "2.5h", int64(9000000000000), false, ""},       // #5
		{"Correct", Timestamp(), "-5h", int64(-18000000000000), false, ""},      // #5
		{"Correct", Timestamp(), "13:10:44", int64(47444000000000), false, ""},  // #6
		{"Correct", Timestamp(), "23:59:59", int64(86399000000000), false, ""},  // #7
		{"Correct", Timestamp(), "00:00:00", int64(0), false, ""},               // #8
		{"Correct", Timestamp(), "00:00:01", int64(1000000000), false, ""},      // #8
		{"Correct", Timestamp(), uint64(2), int64(2), false, ""},
		{"Correct", Timestamp(), nil, 0, false, ""},

		{"Wrong data", Timestamp(), "", nil, true, "decode error: parsing time \"\" as \"15:04:05\": cannot parse \"\" as \"15\""},          // #0
		{"Wrong data", Timestamp(), []byte(""), nil, true, "decode error: unsupported value type: \"slice\""},                               // #1
		{"Wrong data", Timestamp(), 2.2, nil, true, "decode error: unsupported value type: \"float64\""},                                    // #2
		{"Wrong data", Timestamp(), "13:10", nil, true, "decode error: parsing time \"13:10\" as \"15:04:05\": cannot parse \"\" as \":\""}, // #3
		{"Wrong data", Timestamp(), "24:00:00", nil, true, "decode error: parsing time \"24:00:00\": hour out of range"},                    // #4

	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, err := Decode(context.Background(), tt.field, tt.data)
			if tt.wantErr {
				require.Equal(t, tt.errMsg, err.Error())
				return
			}
			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("Decode() got = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestTimestamp_Encode(t *testing.T) {
	tests := []struct {
		name    string
		field   *Field
		data    interface{}
		want    interface{}
		wantErr bool
		errMsg  string
	}{
		{"Correct", Timestamp(), int64(2), int64(2), false, ""},  // #0
		{"Correct", Timestamp(), 2, int64(2), false, ""},         // #1
		{"Correct", Timestamp(), uint64(2), int64(2), false, ""}, // #2

		{"Wrong data", Timestamp(), "", nil, true, "encode error: unsupported value type: \"string\""},        // #0
		{"Wrong data", Timestamp(), []byte(""), nil, true, "encode error: unsupported value type: \"slice\""}, // #1
		{"Wrong data", Timestamp(), 2.2, nil, true, "encode error: unsupported value type: \"float64\""},      // #2

	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, err := Encode(context.Background(), tt.field, tt.data)
			if tt.wantErr {
				require.Equal(t, tt.errMsg, err.Error())
				return
			}
			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("Decode() got = %v, want %v", got, tt.want)
			}
		})
	}
}