// Copyright 2021 TiKV Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// NOTE: The code in this file is based on code from the
// TiDB project, licensed under the Apache License v 2.0
//
// https://github.com/pingcap/tidb/tree/cc5e161ac06827589c4966674597c137cc9e809c/store/tikv/util/misc_test.go
//

// Copyright 2021 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package util

import (
	"testing"
	"time"

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

func TestCompatibleParseGCTime(t *testing.T) {
	assert, require := assert.New(t), require.New(t)

	values := []string{
		"20181218-19:53:37 +0800 CST",
		"20181218-19:53:37 +0800 MST",
		"20181218-19:53:37 +0800 FOO",
		"20181218-19:53:37 +0800 +08",
		"20181218-19:53:37 +0800",
		"20181218-19:53:37 +0800 ",
		"20181218-11:53:37 +0000",
		"20181218-11:53:37.000 +0000",
		"20181218-19:53:37.000 +0800 +08",
	}

	invalidValues := []string{
		"",
		" ",
		"foo",
		"20181218-11:53:37",
		"20181218-19:53:37 +0800CST",
		"20181218-19:53:37 +0800 FOO BAR",
		"20181218-19:53:37 +0800FOOOOOOO BAR",
		"20181218-19:53:37 ",
	}

	expectedTime := time.Date(2018, 12, 18, 11, 53, 37, 0, time.UTC)
	expectedTimeFormatted := "20181218-19:53:37.000 +0800"

	beijing, err := time.LoadLocation("Asia/Shanghai")
	require.Nil(err)

	for _, value := range values {
		t, err := CompatibleParseGCTime(value)
		assert.Nil(err)
		assert.True(t.Equal(expectedTime))

		formatted := t.In(beijing).Format(GCTimeFormat)
		assert.Equal(formatted, expectedTimeFormatted)
	}

	for _, value := range invalidValues {
		_, err = CompatibleParseGCTime(value)
		assert.NotNil(err)
	}
}

func TestTimeDetail(t *testing.T) {
	detail := &TimeDetail{KvReadWallTime: time.Millisecond * 2, TotalRPCWallTime: time.Millisecond * 3}
	assert.Equal(t, "time_detail: {total_kv_read_wall_time: 2ms, tikv_wall_time: 3ms}", detail.String())
	detail = &TimeDetail{
		ProcessTime:      time.Millisecond * 2,
		SuspendTime:      time.Millisecond * 3,
		WaitTime:         time.Millisecond * 4,
		KvReadWallTime:   time.Millisecond * 5,
		TotalRPCWallTime: time.Millisecond * 6,
	}
	assert.Equal(t, "time_detail: {total_process_time: 2ms, total_suspend_time: 3ms, total_wait_time: 4ms, total_kv_read_wall_time: 5ms, tikv_wall_time: 6ms}", detail.String())
}

func TestGetMaxStartKey(t *testing.T) {
	assert := assert.New(t)

	cases := []struct {
		lhs, rhs, expected string
	}{
		{"", "", ""},
		{"", "a", "a"},
		{"a", "a", "a"},
	}

	for _, c := range cases {
		assert.Equal([]byte(c.expected), GetMaxStartKey([]byte(c.lhs), []byte(c.rhs)))
		assert.Equal([]byte(c.expected), GetMaxStartKey([]byte(c.rhs), []byte(c.lhs)))
	}
}

func TestGetMinEndKey(t *testing.T) {
	assert := assert.New(t)

	cases := []struct {
		lhs, rhs, expected string
	}{
		{"", "", ""},
		{"a", "", "a"},
		{"a", "a", "a"},
		{"a", "b", "a"},
	}

	for _, c := range cases {
		assert.Equal([]byte(c.expected), GetMinEndKey([]byte(c.lhs), []byte(c.rhs)))
		assert.Equal([]byte(c.expected), GetMinEndKey([]byte(c.rhs), []byte(c.lhs)))
	}
}
