package util

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

	logpattern_go_proto "github.com/pingcap-inc/alioth/proto"
	"github.com/pingcap-inc/alioth/storage"
	"github.com/pingcap-inc/alioth/storage/keyvalue"
	. "github.com/pingcap/check"
)

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

var _ = Suite(&testLogExtractorSuite{})

type testLogExtractorSuite struct {
}

func (t *testLogExtractorSuite) TestLogPatternRule(c *C) {
	rule := &logpattern_go_proto.LogPatternRule{}
	// empty rule the return true
	res := MatchLogPatternRule(nil, "error")
	c.Assert(res, IsTrue)
	// empty rule the return true
	res = MatchLogPatternRule(nil, "")
	c.Assert(res, IsTrue)
	// empty rule the return true
	res = MatchLogPatternRule(rule, "warn")
	c.Assert(res, IsTrue)

	err := StrictDecodeFile("../../test/extractor/rule.example.cfg", rule)
	c.Assert(err, IsNil)
	c.Assert(rule.LogLevel, DeepEquals, []string{"fatal", "error"})
	// misatch log level
	res = MatchLogPatternRule(rule, "warn")
	c.Assert(res, IsFalse)
	// misatch log level
	res = MatchLogPatternRule(rule, "")
	c.Assert(res, IsFalse)
	// matched log level
	res = MatchLogPatternRule(rule, "Error")
	c.Assert(res, IsTrue)
	// matched log level
	res = MatchLogPatternRule(rule, "Fatal")
	c.Assert(res, IsTrue)
}

func (t *testLogExtractorSuite) TestSaveAndLoadPatternRule(c *C) {
	tmpdir, err := ioutil.TempDir("./", "logpattern_test")
	c.Assert(err, IsNil)
	defer os.RemoveAll(tmpdir)

	store, err := storage.NewStore(tmpdir)
	c.Assert(err, IsNil)

	key, _ := keyvalue.EncodeLogPatternRuleKey()
	wr, err := store.GetDB().Writer(context.Background())
	c.Assert(err, IsNil)

	// write error log pattern rule
	err = wr.Write(key, []byte("xxx"))
	c.Assert(err, IsNil)
	c.Assert(wr.Close(), IsNil)

	rule, err := GetLogPatternRule(store)
	c.Assert(err, NotNil)
	c.Assert(rule, IsNil)

	store.WriteLogPatternRule(context.Background(), &logpattern_go_proto.LogPatternRule{
		LogLevel: []string{"error"},
	})
	rule, err = GetLogPatternRule(store)
	c.Assert(err, IsNil)
	c.Assert(rule, DeepEquals, &logpattern_go_proto.LogPatternRule{
		LogLevel: []string{"error"},
	})

}
