package util

import (
	"io/ioutil"
	"os"
	"testing"

	. "github.com/pingcap/check"
	"github.com/pingcap/schrodinger/buildbot/config"
)

func TestClient(t *testing.T) {
	TestingT(t)
}

var _ = Suite(&testUtilSuite{})

type testUtilSuite struct{}

func (t *testUtilSuite) TestbinTarName(c *C) {
	binName := binTarName("a/b/c/d")
	c.Assert(binName, Equals, "d.tar.gz")
}

func (t *testUtilSuite) TestCopyFile(c *C) {
	content := []byte("temporary file's content")
	tmpfile, _ := ioutil.TempFile("", "example")
	tmpfile.Write(content)
	tmpfile.Close()
	defer os.Remove(tmpfile.Name())
	tmpfile1 := tmpfile.Name() + "1"
	CopyFile(tmpfile.Name(), tmpfile1)
	defer os.Remove(tmpfile1)
	content2, _ := ioutil.ReadFile(tmpfile1)
	c.Assert(string(content), Equals, string(content2))
}

func (t *testUtilSuite) TestgetVersion(c *C) {
	_, err := getVersion("bash")
	c.Assert(err, Equals, nil)
}

func (t *testUtilSuite) TestFormatSnakeCase(c *C) {
	c.Assert(FormatSnakeCase(" ChaosTest_test-test  chaos__chaos--test_ChaosA"), Equals, "chaos-test-test-test-chaos-chaos-test-chaos-a")
	c.Assert(FormatSnakeCase("_-Chaos--Test_--"), Equals, "chaos-test")
	c.Assert(FormatSnakeCase("OK_OK_"), Equals, "ok-ok")
}

func (t *testUtilSuite) TestGetGitHash(c *C) {
	h1 := getGitHash("Git Commit Hash: 9e0d97b2b8e9578612c91db58c896b8b9ef9d4ff\nUTC Build Time:  2018-03-23 02:31:40")
	h2 := "9e0d97b2b8e9578612c91db58c896b8b9ef9d4ff"
	c.Assert(h1, Equals, h2)
}

func (t *testUtilSuite) TestLabelsMapToLabels(c *C) {
	labels := make(map[string]string)
	labels["key1"] = "value1"
	labelStr := LabelsMapToLabels(labels)
	c.Assert(labelStr, Equals, "key1=value1")
}

func (t *testUtilSuite) TestCountDiff(c *C) {
	c.Assert(CountDiff(1, 0), Equals, float64(0))
	c.Assert(CountDiff(1, 1), Equals, float64(0))
	c.Assert(CountDiff(2, 1), Equals, float64(1))
}

func (t *testUtilSuite) TestMatchInArray(c *C) {
	arr := []string{"test1", "", "test2"}
	c.Assert(MatchInArray(arr, "test1"), Equals, true)
	c.Assert(MatchInArray(arr, ""), Equals, true)
	c.Assert(MatchInArray(arr, "test3"), Equals, false)
}

func (t *testUtilSuite) TestMatchInArray2(c *C) {
	arr1 := []string{"test1", "", "test2"}
	c.Assert(MatchInArray2(arr1, "test1"), Equals, true)
	c.Assert(MatchInArray2(arr1, ""), Equals, true)
	c.Assert(MatchInArray2(arr1, "test3"), Equals, false)

	arr2 := []string{}
	c.Assert(MatchInArray2(arr2, "test1"), Equals, true)
	c.Assert(MatchInArray2(arr2, ""), Equals, true)
	c.Assert(MatchInArray2(arr2, "test3"), Equals, true)
}

func (t *testUtilSuite) TestFloat64ToPercentage(c *C) {
	c.Assert(Float64ToPercentage(float64(0.333454)), Equals, "33.35%")
	c.Assert(Float64ToPercentage(float64(-0.333454)), Equals, "-33.35%")
	c.Assert(Float64ToPercentage(float64(0)), Equals, "0.00%")
}

func (t *testUtilSuite) TestFormatFloat64(c *C) {
	c.Assert(FormatFloat64(float64(33.333454)), Equals, "33.33")
}

func (t *testUtilSuite) TestRemoveRep(c *C) {
	t1 := []string{"aa", "bb", "cc", "aa"}
	c.Assert(RemoveRep(t1), DeepEquals, []string{"aa", "bb", "cc"})

	t2 := []string{"", "", "aa", "aa"}
	c.Assert(RemoveRep(t2), DeepEquals, []string{"", "aa"})
}

func (t *testUtilSuite) TestMergeMaps(c *C) {
	m1 := make(map[string]string)
	m2 := make(map[string]string)
	m1["node"] = "general"
	m2["test"] = "test1"
	c.Assert(MergeMaps(m1, m2), DeepEquals, map[string]string{"node": "general", "test": "test1"})
}

func (t *testUtilSuite) TestGetHashByBranchAndTag(c *C) {
	hash, err := GetHashByBranchAndTag("", "v3.0.0-rc.2", "tidb",
		config.GetBuildConfig().BaseConfig.DownloadAddr)
	c.Assert(err, Equals, nil)
	c.Assert(hash, Equals, "06f3f63d5a87e7f0436c0618cf524fea7172eb93")

	hash, err = GetHashByBranchAndTag("release-2.1", "", "pd",
		config.GetBuildConfig().BaseConfig.DownloadAddr)
	c.Assert(err, Equals, nil)
	c.Assert(len(hash), Equals, 40)

	hash, err = GetHashByBranchAndTag("", "", "pd",
		config.GetBuildConfig().BaseConfig.DownloadAddr)
	c.Assert(err, NotNil)

	hash, err = GetHashByBranchAndTag("", "v3.0.0-rc.2", "",
		config.GetBuildConfig().BaseConfig.DownloadAddr)
	c.Assert(err, NotNil)
}

func (t *testUtilSuite) TestExtractRepoInfo(c *C) {
	or, repo, err := ExtractRepoInfo("tidb")
	c.Assert(err, Equals, nil)
	c.Assert(or, Equals, "")
	c.Assert(repo, Equals, "tidb")

	or, repo, err = ExtractRepoInfo("https://github.com/pingcap/tidb.git")
	c.Assert(err, Equals, nil)
	c.Assert(or, Equals, "pingcap")
	c.Assert(repo, Equals, "tidb")

	or, repo, err = ExtractRepoInfo("http://github.com/pingcap/tidb.git")
	c.Assert(err, Equals, nil)
	c.Assert(or, Equals, "pingcap")
	c.Assert(repo, Equals, "tidb")

	or, repo, err = ExtractRepoInfo("ssh@github.com/pingcap/tidb.git")
	c.Assert(err, Equals, nil)
	c.Assert(or, Equals, "pingcap")
	c.Assert(repo, Equals, "tidb")

	or, repo, err = ExtractRepoInfo("ssh@github.com/pingcap/tidb")
	c.Assert(err, Equals, nil)
	c.Assert(or, Equals, "pingcap")
	c.Assert(repo, Equals, "tidb")

	or, repo, err = ExtractRepoInfo("github.com/pingcap/tidb")
	c.Assert(err, Equals, nil)
	c.Assert(or, Equals, "pingcap")
	c.Assert(repo, Equals, "tidb")
}
