package api

import (
	"fmt"
	"net/http"
	"testing"

	"github.com/cactus/go-statsd-client/statsd"
	. "github.com/smartystreets/goconvey/convey"
	"goji.io/pattern"
	"golang.org/x/net/context"

	"code.justin.tv/live/yt-live-annotations/app/api/mocks"
	"code.justin.tv/live/yt-live-annotations/youtube"
)

func Test_getAnnotationsEnabled(t *testing.T) {
	testUserID := "24534"
	Convey("internal server error for errors", t, func() {
		ctx := context.Background()
		ctx = context.WithValue(ctx, pattern.Variable("user_id"), testUserID)
		backend := &mocks.Backend{}
		s := &Server{
			backend: backend,
			stats:   &statsd.NoopClient{},
		}
		r, _ := http.NewRequest("GET", "/enabled", nil)

		err := fmt.Errorf("what")

		backend.On("GetAnnotationsEnabled", ctx, testUserID).Return(false, err)
		w := makeTestRequest(s.getAnnotationsEnabled, ctx, r)

		So(w.Code, ShouldEqual, http.StatusInternalServerError)
	})

	Convey("success", t, func() {
		ctx := context.Background()
		ctx = context.WithValue(ctx, pattern.Variable("user_id"), testUserID)
		backend := &mocks.Backend{}
		s := &Server{
			backend: backend,
			stats:   &statsd.NoopClient{},
		}
		r, _ := http.NewRequest("GET", "/enabled", nil)

		backend.On("GetAnnotationsEnabled", ctx, testUserID).Return(false, nil)
		w := makeTestRequest(s.getAnnotationsEnabled, ctx, r)

		So(w.Code, ShouldEqual, http.StatusOK)
		So(w.Body.String(), ShouldContainSubstring, "false")
	})
}

func Test_setAnnotationsEnabled(t *testing.T) {
	testUserID := "24534"
	Convey("internal server error for errors", t, func() {
		ctx := context.Background()
		ctx = context.WithValue(ctx, pattern.Variable("user_id"), testUserID)
		backend := &mocks.Backend{}
		s := &Server{
			backend: backend,
			stats:   &statsd.NoopClient{},
		}
		r, _ := http.NewRequest("GET", "/enabled", nil)

		err := fmt.Errorf("what")

		backend.On("EnableAnnotations", ctx, testUserID).Return(err)
		w := makeTestRequest(s.setAnnotationsEnabled, ctx, r)

		So(w.Code, ShouldEqual, http.StatusInternalServerError)
	})

	Convey("success", t, func() {
		ctx := context.Background()
		ctx = context.WithValue(ctx, pattern.Variable("user_id"), testUserID)
		backend := &mocks.Backend{}
		s := &Server{
			backend: backend,
			stats:   &statsd.NoopClient{},
		}
		r, _ := http.NewRequest("GET", "/enabled", nil)

		backend.On("EnableAnnotations", ctx, testUserID).Return(nil)
		w := makeTestRequest(s.setAnnotationsEnabled, ctx, r)

		So(w.Code, ShouldEqual, http.StatusOK)
		So(w.Body.String(), ShouldContainSubstring, "true")
	})
}

func Test_setAnnotationsDisabled(t *testing.T) {
	testUserID := "24534"
	Convey("internal server error for errors", t, func() {
		ctx := context.Background()
		ctx = context.WithValue(ctx, pattern.Variable("user_id"), testUserID)
		backend := &mocks.Backend{}
		s := &Server{
			backend: backend,
			stats:   &statsd.NoopClient{},
		}
		r, _ := http.NewRequest("GET", "/enabled", nil)

		err := fmt.Errorf("what")

		backend.On("DisableAnnotations", ctx, testUserID).Return(err)
		w := makeTestRequest(s.setAnnotationsDisabled, ctx, r)

		So(w.Code, ShouldEqual, http.StatusInternalServerError)
	})

	Convey("success", t, func() {
		ctx := context.Background()
		ctx = context.WithValue(ctx, pattern.Variable("user_id"), testUserID)
		backend := &mocks.Backend{}
		yt := &mocks.YT{}
		s := &Server{
			backend: backend,
			yt:      yt,
			stats:   &statsd.NoopClient{},
		}
		r, _ := http.NewRequest("GET", "/enabled", nil)

		backend.On("DisableAnnotations", ctx, testUserID).Return(nil)
		yt.On("SetYoutubeAnnotationsStatus", ctx, testUserID, youtube.StatusDown).Return(nil)
		w := makeTestRequest(s.setAnnotationsDisabled, ctx, r)

		So(w.Code, ShouldEqual, http.StatusOK)
		So(w.Body.String(), ShouldContainSubstring, "false")
	})
}
