package gexec_test

import (
	"os/exec"
	"syscall"
	"time"

	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"

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

var _ = Describe("Session", func() {
	var command *exec.Cmd
	var session *Session

	var outWriter, errWriter *Buffer

	BeforeEach(func() {
		outWriter = nil
		errWriter = nil
	})

	JustBeforeEach(func() {
		command = exec.Command(fireflyPath)
		var err error
		session, err = Start(command, outWriter, errWriter)
		Ω(err).ShouldNot(HaveOccurred())
	})

	Context("running a command", func() {
		It("should start the process", func() {
			Ω(command.Process).ShouldNot(BeNil())
		})

		It("should wrap the process's stdout and stderr with gbytes buffers", func(done Done) {
			Eventually(session.Out).Should(Say("We've done the impossible, and that makes us mighty"))
			Eventually(session.Err).Should(Say("Ah, curse your sudden but inevitable betrayal!"))
			defer session.Out.CancelDetects()

			select {
			case <-session.Out.Detect("Can we maybe vote on the whole murdering people issue"):
				Eventually(session).Should(Exit(0))
			case <-session.Out.Detect("I swear by my pretty floral bonnet, I will end you."):
				Eventually(session).Should(Exit(1))
			case <-session.Out.Detect("My work's illegal, but at least it's honest."):
				Eventually(session).Should(Exit(2))
			}

			close(done)
		})

		It("should satisfy the gbytes.BufferProvider interface, passing Stdout", func() {
			Eventually(session).Should(Say("We've done the impossible, and that makes us mighty"))
			Eventually(session).Should(Exit())
		})
	})

	Describe("providing the exit code", func() {
		It("should provide the app's exit code", func() {
			Ω(session.ExitCode()).Should(Equal(-1))

			Eventually(session).Should(Exit())
			Ω(session.ExitCode()).Should(BeNumerically(">=", 0))
			Ω(session.ExitCode()).Should(BeNumerically("<", 3))
		})
	})

	Describe("wait", func() {
		It("should wait till the command exits", func() {
			Ω(session.ExitCode()).Should(Equal(-1))
			Ω(session.Wait().ExitCode()).Should(BeNumerically(">=", 0))
			Ω(session.Wait().ExitCode()).Should(BeNumerically("<", 3))
		})
	})

	Describe("exited", func() {
		It("should close when the command exits", func() {
			Eventually(session.Exited).Should(BeClosed())
			Ω(session.ExitCode()).ShouldNot(Equal(-1))
		})
	})

	Describe("kill", func() {
		It("should kill the command and wait for it to exit", func() {
			session, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
			Ω(err).ShouldNot(HaveOccurred())

			session.Kill()
			Ω(session).ShouldNot(Exit(), "Should not exit immediately...")
			Eventually(session).Should(Exit(128 + 9))
		})
	})

	Describe("interrupt", func() {
		It("should interrupt the command", func() {
			session, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
			Ω(err).ShouldNot(HaveOccurred())

			session.Interrupt()
			Ω(session).ShouldNot(Exit(), "Should not exit immediately...")
			Eventually(session).Should(Exit(128 + 2))
		})
	})

	Describe("terminate", func() {
		It("should terminate the command", func() {
			session, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
			Ω(err).ShouldNot(HaveOccurred())

			session.Terminate()
			Ω(session).ShouldNot(Exit(), "Should not exit immediately...")
			Eventually(session).Should(Exit(128 + 15))
		})
	})

	Describe("signal", func() {
		It("should send the signal to the command", func() {
			session, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
			Ω(err).ShouldNot(HaveOccurred())

			session.Signal(syscall.SIGABRT)
			Ω(session).ShouldNot(Exit(), "Should not exit immediately...")
			Eventually(session).Should(Exit(128 + 6))
		})
	})

	Context("when the command exits", func() {
		It("should close the buffers", func() {
			Eventually(session).Should(Exit())

			Ω(session.Out.Closed()).Should(BeTrue())
			Ω(session.Err.Closed()).Should(BeTrue())

			Ω(session.Out).Should(Say("We've done the impossible, and that makes us mighty"))
		})

		var So = It

		So("this means that eventually should short circuit", func() {
			t := time.Now()
			failures := InterceptGomegaFailures(func() {
				Eventually(session).Should(Say("blah blah blah blah blah"))
			})
			Ω(time.Since(t)).Should(BeNumerically("<=", 500*time.Millisecond))
			Ω(failures).Should(HaveLen(1))
		})
	})

	Context("when wrapping out and err", func() {
		BeforeEach(func() {
			outWriter = NewBuffer()
			errWriter = NewBuffer()
		})

		It("should route to both the provided writers and the gbytes buffers", func() {
			Eventually(session.Out).Should(Say("We've done the impossible, and that makes us mighty"))
			Eventually(session.Err).Should(Say("Ah, curse your sudden but inevitable betrayal!"))

			Ω(outWriter.Contents()).Should(ContainSubstring("We've done the impossible, and that makes us mighty"))
			Ω(errWriter.Contents()).Should(ContainSubstring("Ah, curse your sudden but inevitable betrayal!"))

			Eventually(session).Should(Exit())

			Ω(outWriter.Contents()).Should(Equal(session.Out.Contents()))
			Ω(errWriter.Contents()).Should(Equal(session.Err.Contents()))
		})
	})

	Describe("when the command fails to start", func() {
		It("should return an error", func() {
			_, err := Start(exec.Command("agklsjdfas"), nil, nil)
			Ω(err).Should(HaveOccurred())
		})
	})
})
