package matcher

import (
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Toleration", func() {
	Context("TolerationByDuration", func() {
		It("should always passed with AlwaysTrue", func() {
			matcher := TolerateByDuration(BeTrue(), 100*time.Millisecond)
			success, err := matcher.Match(true)
			Expect(err).ShouldNot(HaveOccurred())
			Expect(success).Should(BeTrue())

			time.Sleep(100 * time.Millisecond)
			success, err = matcher.Match(true)
			Expect(err).ShouldNot(HaveOccurred())
			Expect(success).Should(BeTrue())

			time.Sleep(100 * time.Millisecond)
			success, err = matcher.Match(true)
			Expect(err).ShouldNot(HaveOccurred())
			Expect(success).Should(BeTrue())
		})

		It("should eventually failed with AlwaysFalse", func() {
			matcher := TolerateByDuration(BeTrue(), 300*time.Millisecond)
			success, err := matcher.Match(false)
			Expect(err).ShouldNot(HaveOccurred())
			Expect(success).Should(BeTrue()) // immediately True

			time.Sleep(100 * time.Millisecond)
			success, err = matcher.Match(false)
			Expect(err).ShouldNot(HaveOccurred())
			Expect(success).Should(BeTrue()) // 100 ms later True

			time.Sleep(100 * time.Millisecond)
			success, err = matcher.Match(false)
			Expect(err).ShouldNot(HaveOccurred())
			Expect(success).Should(BeTrue()) // 200 ms later True

			time.Sleep(200 * time.Millisecond)
			success, err = matcher.Match(false)
			Expect(err).ShouldNot(HaveOccurred())
			Expect(success).Should(BeFalse()) // 400 ms later False
		})

		It("should not match eventually with failure-pass-failure", func() {
			matcher := TolerateByDuration(BeTrue(), 500*time.Millisecond)
			success, err := matcher.Match(false)
			Expect(err).ShouldNot(HaveOccurred())
			Expect(success).Should(BeTrue())

			time.Sleep(200 * time.Millisecond)
			_, err = matcher.Match(true) // now pass
			Expect(err).ShouldNot(HaveOccurred())

			_, err = matcher.Match(false)
			Expect(err).ShouldNot(HaveOccurred())

			time.Sleep(200 * time.Millisecond)
			success, err = matcher.Match(false)
			Expect(err).ShouldNot(HaveOccurred())
			Expect(success).Should(BeTrue())

			time.Sleep(200 * time.Millisecond)
			success, err = matcher.Match(false)
			Expect(err).ShouldNot(HaveOccurred())
			Expect(success).Should(BeFalse())
			Expect(matcher.FailureMessage(false)).To(ContainSubstring("Diagnose Info"))
		})
	})
})
