package goscaffold

import (
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"sync/atomic"
	"time"

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

var insecureClient = &http.Client{
	Transport: &http.Transport{
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
		},
	},
}

var _ = Describe("Scaffold Tests", func() {
	It("Validate framework", func() {
		s := CreateHTTPScaffold()
		stopChan := make(chan error)
		err := s.Open()
		Expect(err).Should(Succeed())

		go func() {
			fmt.Fprintf(GinkgoWriter, "Gonna listen on %s\n", s.InsecureAddress())
			stopErr := s.Listen(&testHandler{})
			fmt.Fprintf(GinkgoWriter, "Done listening\n")
			stopChan <- stopErr
		}()

		Eventually(func() bool {
			return testGet(s, "")
		}, 5*time.Second).Should(BeTrue())
		resp, err := http.Get(fmt.Sprintf("http://%s", s.InsecureAddress()))
		Expect(err).Should(Succeed())
		resp.Body.Close()
		Expect(resp.StatusCode).Should(Equal(200))
		shutdownErr := errors.New("Validate")
		s.Shutdown(shutdownErr)
		Eventually(stopChan).Should(Receive(Equal(shutdownErr)))
	})

	It("Separate management port", func() {
		s := CreateHTTPScaffold()
		s.SetManagementPort(0)
		stopChan := make(chan error)
		err := s.Open()
		Expect(err).Should(Succeed())

		go func() {
			fmt.Fprintf(GinkgoWriter, "Gonna listen on %s and %s\n",
				s.InsecureAddress(), s.ManagementAddress())
			stopErr := s.Listen(&testHandler{})
			fmt.Fprintf(GinkgoWriter, "Done listening\n")
			stopChan <- stopErr
		}()

		// Just make sure that it's up
		Eventually(func() bool {
			return testGet(s, "")
		}, 5*time.Second).Should(BeTrue())
		resp, err := http.Get(fmt.Sprintf("http://%s", s.InsecureAddress()))
		Expect(err).Should(Succeed())
		resp.Body.Close()
		Expect(resp.StatusCode).Should(Equal(200))
		resp, err = http.Get(fmt.Sprintf("http://%s", s.ManagementAddress()))
		Expect(err).Should(Succeed())
		resp.Body.Close()
		Expect(resp.StatusCode).Should(Equal(404))
		shutdownErr := errors.New("Validate")
		s.Shutdown(shutdownErr)
		Eventually(stopChan).Should(Receive(Equal(shutdownErr)))
	})

	It("Shutdown", func() {
		s := CreateHTTPScaffold()
		s.SetHealthPath("/health")
		s.SetReadyPath("/ready")
		stopChan := make(chan error)
		err := s.Open()
		Expect(err).Should(Succeed())

		go func() {
			stopErr := s.Listen(&testHandler{})
			stopChan <- stopErr
		}()

		go func() {
			code, _ := getText(fmt.Sprintf("http://%s?delay=1s", s.InsecureAddress()))
			Expect(code).Should(Equal(200))
		}()

		// Just make sure server is listening
		Eventually(func() bool {
			return testGet(s, "")
		}, 5*time.Second).Should(BeTrue())

		// Ensure that we are healthy and ready
		code, _ := getText(fmt.Sprintf("http://%s/health", s.InsecureAddress()))
		Expect(code).Should(Equal(200))
		code, _ = getText(fmt.Sprintf("http://%s/ready", s.InsecureAddress()))
		Expect(code).Should(Equal(200))

		// Previous call prevents server from exiting
		Consistently(stopChan, 250*time.Millisecond).ShouldNot(Receive())

		// Tell the server to try and exit
		stopErr := errors.New("Stop")
		s.Shutdown(stopErr)

		// Should take one second -- in the meantime, calls should fail with 503,
		// health should be good, but ready should be bad
		code, _ = getText(fmt.Sprintf("http://%s", s.InsecureAddress()))
		Expect(code).Should(Equal(503))
		code, _ = getText(fmt.Sprintf("http://%s/ready", s.InsecureAddress()))
		Expect(code).Should(Equal(503))
		code, _ = getText(fmt.Sprintf("http://%s/health", s.InsecureAddress()))
		Expect(code).Should(Equal(200))

		// Do a bunch more stops because we are funny that way.
		// We just want to make sure that we don't hang if we stop a FEW times.
		for i := 0; i < 25; i++ {
			s.Shutdown(stopErr)
		}

		// But in less than two seconds, server should be down
		Eventually(stopChan, 2*time.Second).Should(Receive(Equal(stopErr)))
		// Calls should now fail
		Eventually(func() bool {
			return testGet(s, "")
		}, time.Second).Should(BeFalse())
	})

	It("Markdown", func() {
		var markedDown int32

		s := CreateHTTPScaffold()
		s.SetHealthPath("/health")
		s.SetReadyPath("/ready")
		s.SetMarkdown("POST", "/markdown", func() {
			atomic.StoreInt32(&markedDown, 1)
		})

		stopChan := make(chan error)
		err := s.Open()
		Expect(err).Should(Succeed())

		go func() {
			listenErr := s.Listen(&testHandler{})
			stopChan <- listenErr
		}()

		// Just make sure server is listening
		Eventually(func() bool {
			return testGet(s, "")
		}, 5*time.Second).Should(BeTrue())

		// Ensure that we are healthy and ready
		code, _ := getText(fmt.Sprintf("http://%s/health", s.InsecureAddress()))
		Expect(code).Should(Equal(200))
		code, _ = getText(fmt.Sprintf("http://%s/ready", s.InsecureAddress()))
		Expect(code).Should(Equal(200))

		// Mark the server down, but don't stop it
		resp, err := http.Post(fmt.Sprintf("http://%s/markdown", s.InsecureAddress()),
			"text/plain", strings.NewReader("Goodbye!"))
		Expect(err).Should(Succeed())
		resp.Body.Close()
		Expect(resp.StatusCode).Should(Equal(200))

		// Server should immediately be marked down, not ready, but healthy
		Expect(atomic.LoadInt32(&markedDown)).Should(BeEquivalentTo(1))
		code, _ = getText(fmt.Sprintf("http://%s", s.InsecureAddress()))
		Expect(code).Should(Equal(503))
		code, _ = getText(fmt.Sprintf("http://%s/ready", s.InsecureAddress()))
		Expect(code).Should(Equal(503))
		code, _ = getText(fmt.Sprintf("http://%s/health", s.InsecureAddress()))
		Expect(code).Should(Equal(200))

		// Server should not have stopped yet
		Consistently(stopChan).ShouldNot(Receive())

		stopErr := errors.New("Test stop")
		s.Shutdown(stopErr)
		Eventually(stopChan).Should(Receive(Equal(stopErr)))
	})

	It("Health Check Functions", func() {
		status := int32(OK)
		var healthErr = &atomic.Value{}

		statusFunc := func() (HealthStatus, error) {
			stat := HealthStatus(atomic.LoadInt32(&status))
			av := healthErr.Load()
			if av != nil {
				errPtr := av.(*error)
				return stat, *errPtr
			}
			return stat, nil
		}

		s := CreateHTTPScaffold()
		s.SetManagementPort(0)
		s.SetHealthPath("/health")
		s.SetReadyPath("/ready")
		s.SetHealthChecker(statusFunc)
		stopChan := make(chan error)
		err := s.Open()
		Expect(err).Should(Succeed())

		go func() {
			fmt.Fprintf(GinkgoWriter, "Gonna listen on %s and %s\n",
				s.InsecureAddress(), s.ManagementAddress())
			stopErr := s.Listen(&testHandler{})
			fmt.Fprintf(GinkgoWriter, "Done listening\n")
			stopChan <- stopErr
		}()

		// Just make sure that it's up
		Eventually(func() bool {
			return testGet(s, "")
		}, 5*time.Second).Should(BeTrue())

		// Health should be good
		code, _ := getText(fmt.Sprintf("http://%s/health", s.ManagementAddress()))
		Expect(code).Should(Equal(200))
		code, _ = getText(fmt.Sprintf("http://%s/ready", s.ManagementAddress()))
		Expect(code).Should(Equal(200))

		// Mark down to "unhealthy" state. Should be bad.
		atomic.StoreInt32(&status, int32(Failed))
		code, bod := getText(fmt.Sprintf("http://%s/health", s.ManagementAddress()))
		Expect(code).Should(Equal(503))
		Expect(bod).Should(Equal("Failed"))
		code, _ = getText(fmt.Sprintf("http://%s/ready", s.ManagementAddress()))
		Expect(code).Should(Equal(503))

		// Change to merely "not ready" state. Should be healthy but not ready.
		atomic.StoreInt32(&status, int32(NotReady))
		code, _ = getText(fmt.Sprintf("http://%s/health", s.ManagementAddress()))
		Expect(code).Should(Equal(200))
		code, bod = getText(fmt.Sprintf("http://%s/ready", s.ManagementAddress()))
		Expect(code).Should(Equal(503))
		Expect(bod).Should(Equal("NotReady"))

		// Customize the error message.
		customErr := errors.New("Custom")
		healthErr.Store(&customErr)
		code, bod = getText(fmt.Sprintf("http://%s/ready", s.ManagementAddress()))
		Expect(code).Should(Equal(503))
		Expect(bod).Should(Equal("Custom"))

		// Check it in JSON
		code, js := getJSON(fmt.Sprintf("http://%s/ready", s.ManagementAddress()))
		Expect(code).Should(Equal(503))
		Expect(js["status"]).Should(Equal("NotReady"))
		Expect(js["reason"]).Should(Equal("Custom"))

		// Mark back up. Should be all good
		atomic.StoreInt32(&status, int32(OK))
		code, _ = getText(fmt.Sprintf("http://%s/health", s.ManagementAddress()))
		Expect(code).Should(Equal(200))
		code, _ = getText(fmt.Sprintf("http://%s/ready", s.ManagementAddress()))
		Expect(code).Should(Equal(200))

		s.Shutdown(nil)
		Eventually(stopChan).Should(Receive(Equal(ErrManualStop)))
	})

	It("Secure And Insecure Ports", func() {
		s := CreateHTTPScaffold()
		s.SetSecurePort(0)
		s.SetKeyFile("./testkeys/clearkey.pem", nil)
		s.SetCertFile("./testkeys/clearcert.pem")
		stopChan := make(chan error)
		err := s.Open()
		Expect(err).Should(Succeed())

		go func() {
			fmt.Fprintf(GinkgoWriter, "Gonna listen on %s and %s\n",
				s.InsecureAddress(), s.SecureAddress())
			stopErr := s.Listen(&testHandler{})
			fmt.Fprintf(GinkgoWriter, "Done listening\n")
			stopChan <- stopErr
		}()

		Eventually(func() bool {
			return testGet(s, "")
		}, 5*time.Second).Should(BeTrue())
		Eventually(func() bool {
			return testGetSecure(s, "")
		}, time.Second).Should(BeTrue())

		shutdownErr := errors.New("Validate")
		s.Shutdown(shutdownErr)
		Eventually(stopChan).Should(Receive(Equal(shutdownErr)))
	})

	It("Secure Port Only", func() {
		s := CreateHTTPScaffold()
		s.SetSecurePort(0)
		s.SetInsecurePort(-1)
		s.SetKeyFile("./testkeys/clearkey.pem", nil)
		s.SetCertFile("./testkeys/clearcert.pem")
		stopChan := make(chan error)
		err := s.Open()
		Expect(err).Should(Succeed())
		Expect(s.InsecureAddress()).Should(BeEmpty())

		go func() {
			fmt.Fprintf(GinkgoWriter, "Gonna listen on %s\n",
				s.SecureAddress())
			stopErr := s.Listen(&testHandler{})
			fmt.Fprintf(GinkgoWriter, "Done listening\n")
			stopChan <- stopErr
		}()

		Eventually(func() bool {
			return testGetSecure(s, "")
		}, 5*time.Second).Should(BeTrue())

		shutdownErr := errors.New("Validate")
		s.Shutdown(shutdownErr)
		Eventually(stopChan).Should(Receive(Equal(shutdownErr)))
	})

	It("Secure Port Encrypted Key", func() {
		s := CreateHTTPScaffold()
		s.SetSecurePort(0)
		s.SetInsecurePort(-1)
		s.SetKeyFile("./testkeys/serverkey.pem", func() []byte {
			return []byte("secure")
		})
		s.SetCertFile("./testkeys/servercert.pem")
		stopChan := make(chan error)
		err := s.Open()
		Expect(err).Should(Succeed())
		Expect(s.InsecureAddress()).Should(BeEmpty())

		go func() {
			fmt.Fprintf(GinkgoWriter, "Gonna listen on %s\n",
				s.SecureAddress())
			stopErr := s.Listen(&testHandler{})
			fmt.Fprintf(GinkgoWriter, "Done listening\n")
			stopChan <- stopErr
		}()

		Eventually(func() bool {
			return testGetSecure(s, "")
		}, 5*time.Second).Should(BeTrue())

		shutdownErr := errors.New("Validate")
		s.Shutdown(shutdownErr)
		Eventually(stopChan).Should(Receive(Equal(shutdownErr)))
	})

	It("Read PEM files", func() {
		_, t, err := decodePEM("./testkeys/clearkey.pem", nil)
		Expect(err).Should(Succeed())
		Expect(t).Should(Equal("RSA PRIVATE KEY"))
		_, t, err = decodePEM("./testkeys/clearcert.pem", nil)
		Expect(err).Should(Succeed())
		Expect(t).Should(Equal("CERTIFICATE"))
		_, err = getCertificate("./testkeys/clearcert.pem", "./testkeys/clearkey.pem", nil)
		Expect(err).Should(Succeed())

		_, _, err = decodePEM("./testkeys/servercert.pem", nil)
		Expect(err).Should(Succeed())
		_, _, err = decodePEM("./testkeys/serverkey.pem", nil)
		Expect(err).ShouldNot(Succeed())
		_, _, err = decodePEM("./testkeys/serverkey.pem", func() []byte {
			return []byte("notsecure")
		})
		Expect(err).ShouldNot(Succeed())
		_, _, err = decodePEM("./testkeys/serverkey.pem", func() []byte {
			return []byte("secure")
		})
		Expect(err).Should(Succeed())
		_, err = getCertificate("./testkeys/servercert.pem", "./testkeys/serverkey.pem", func() []byte {
			return []byte("notsecure")
		})
	})
})

func getText(url string) (int, string) {
	req, err := http.NewRequest("GET", url, nil)
	Expect(err).Should(Succeed())
	req.Header.Set("Accept", "text/plain")
	resp, err := http.DefaultClient.Do(req)
	Expect(err).Should(Succeed())
	defer resp.Body.Close()
	bod, err := ioutil.ReadAll(resp.Body)
	Expect(err).Should(Succeed())
	return resp.StatusCode, string(bod)
}

func getJSON(url string) (int, map[string]string) {
	req, err := http.NewRequest("GET", url, nil)
	Expect(err).Should(Succeed())
	req.Header.Set("Accept", "application/json")
	resp, err := http.DefaultClient.Do(req)
	Expect(err).Should(Succeed())
	defer resp.Body.Close()
	bod, err := ioutil.ReadAll(resp.Body)
	Expect(err).Should(Succeed())
	var vals map[string]string
	err = json.Unmarshal(bod, &vals)
	Expect(err).Should(Succeed())
	return resp.StatusCode, vals
}

func testGet(s *HTTPScaffold, path string) bool {
	resp, err := http.Get(fmt.Sprintf("http://%s", s.InsecureAddress()))
	if err != nil {
		fmt.Fprintf(GinkgoWriter, "Get %s = %s\n", path, err)
		return false
	}
	resp.Body.Close()
	if resp.StatusCode != 200 {
		fmt.Fprintf(GinkgoWriter, "Get %s = %d\n", path, resp.StatusCode)
		return false
	}
	return true
}

func testGetSecure(s *HTTPScaffold, path string) bool {
	resp, err := insecureClient.Get(fmt.Sprintf("https://%s", s.SecureAddress()))
	if err != nil {
		fmt.Fprintf(GinkgoWriter, "Get %s = %s\n", path, err)
		return false
	}
	resp.Body.Close()
	if resp.StatusCode != 200 {
		fmt.Fprintf(GinkgoWriter, "Get %s = %d\n", path, resp.StatusCode)
		return false
	}
	return true
}

type testHandler struct {
}

func (h *testHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
	var err error
	var delayTime time.Duration

	delayStr := req.URL.Query().Get("delay")
	if delayStr != "" {
		delayTime, err = time.ParseDuration(delayStr)
		if err != nil {
			resp.WriteHeader(http.StatusBadRequest)
			return
		}
	}

	if delayTime > 0 {
		time.Sleep(delayTime)
	}
}
