// TestServerTime calls the GetTime method of the pubnubMessaging to test the time
func TestServerTime(t *testing.T) {
	pubnubInstance := pubnubMessaging.PubnubInit("demo", "demo", "", "", false, "")

	returnTimeChannel := make(chan []byte)
	go pubnubInstance.GetTime(returnTimeChannel)
	ParseTimeResponse(returnTimeChannel, t)
}
// TestSuccessCodeAndInfoWithSecretAndEncryption sends out an encrypted
// secret keyed message to the pubnub channel
// The response is parsed and should match the 'sent' status.
// publishSuccessMessage is defined in the common.go file
func TestSuccessCodeAndInfoWithSecretAndEncryption(t *testing.T) {
	pubnubInstance := pubnubMessaging.PubnubInit("demo", "demo", "secret", "enigma", false, "")
	channel := "testChannel"
	message := "Pubnub API Usage Example"
	returnChannel := make(chan []byte)
	go pubnubInstance.Publish(channel, message, returnChannel)

	ParsePublishResponse(returnChannel, t, channel, publishSuccessMessage, "SuccessCodeAndInfoWithSecretAndEncryption")
}
// TestSubscriptionForSimpleMessage first subscribes to a pubnub channel and then publishes
// a message on the same pubnub channel. The subscribe response should receive this same message.
func TestSubscriptionForSimpleMessage(t *testing.T) {
	pubnubInstance := pubnubMessaging.PubnubInit("demo", "demo", "", "", false, "")

	channel := "testChannel"

	returnSubscribeChannel := make(chan []byte)
	go pubnubInstance.Subscribe(channel, returnSubscribeChannel, false)
	ParseSubscribeResponse(pubnubInstance, returnSubscribeChannel, t, channel, "", "SubscriptionConnectedForSimple", "")
}
// TestMultiSubscriptionConnectStatus send out a pubnub multi channel subscribe request and
// parses the response for multiple connection status.
func TestMultiSubscriptionConnectStatus(t *testing.T) {
	pubnubInstance := pubnubMessaging.PubnubInit("demo", "demo", "", "", false, "")
	testName := "TestMultiSubscriptionConnectStatus"
	channels := "testChannel1,testChannel2"

	returnSubscribeChannel := make(chan []byte)
	go pubnubInstance.Subscribe(channels, returnSubscribeChannel, false)
	ParseSubscribeResponseForMultipleChannels(returnSubscribeChannel, channels, t, testName)
}
// TestUnsubscribe will subscribe to a pubnub channel and then send an unsubscribe request
// The response should contain 'unsubscribed'
func TestUnsubscribe(t *testing.T) {
	pubnubInstance := pubnubMessaging.PubnubInit("demo", "demo", "", "", false, "")

	channel := "testChannel"

	returnSubscribeChannel := make(chan []byte)
	go pubnubInstance.Subscribe(channel, returnSubscribeChannel, false)
	ParseSubscribeResponseAndCallUnsubscribe(pubnubInstance, returnSubscribeChannel, t, channel, "connected")
}
// TestUnsubscribeNotSubscribed will try to unsubscribe a non subscribed pubnub channel.
// The response should contain 'not subscribed'
func TestUnsubscribeNotSubscribed(t *testing.T) {
	pubnubInstance := pubnubMessaging.PubnubInit("demo", "demo", "", "", false, "")

	currentTime := time.Now()
	channel := "testChannel" + currentTime.Format("20060102150405")

	returnUnsubscribeChannel := make(chan []byte)
	go pubnubInstance.Unsubscribe(channel, returnUnsubscribeChannel)
	ParseUnsubscribeResponse(returnUnsubscribeChannel, t, channel, "not subscribed")
}
// TestNullMessage sends out a null message to a pubnub channel. The response should
// be an "Invalid Message".
func TestNullMessage(t *testing.T) {
	pubnubInstance := pubnubMessaging.PubnubInit("demo", "demo", "", "", false, "")
	channel := "testChannel"
	var message interface{}
	message = nil
	returnChannel := make(chan []byte)

	go pubnubInstance.Publish(channel, message, returnChannel)

	ParsePublishResponse(returnChannel, t, channel, "Invalid Message", "NullMessage")
}
// TestSuccessCodeAndInfoForComplexMessage2WithEncryption sends out an
// encypted complex message to the pubnub channel
// The response is parsed and should match the 'sent' status.
// publishSuccessMessage and InitComplexMessage is defined in the common.go file
func TestSuccessCodeAndInfoForComplexMessage2WithEncryption(t *testing.T) {
	pubnubInstance := pubnubMessaging.PubnubInit("demo", "demo", "", "enigma", false, "")
	channel := "testChannel"

	customComplexMessage := InitComplexMessage()

	returnChannel := make(chan []byte)
	go pubnubInstance.Publish(channel, customComplexMessage, returnChannel)

	ParsePublishResponse(returnChannel, t, channel, publishSuccessMessage, "SuccessCodeAndInfoForComplexMessage2WithEncryption")
}
// TestSubscriptionAlreadySubscribed sends out a subscribe request to a pubnub channel
// and when connected sends out another subscribe request. The response for the second
func TestSubscriptionAlreadySubscribed(t *testing.T) {
	pubnubInstance := pubnubMessaging.PubnubInit("demo", "demo", "", "", false, "")

	channel := "testChannel"

	returnSubscribeChannel := make(chan []byte)
	go pubnubInstance.Subscribe(channel, returnSubscribeChannel, false)
	returnSubscribeChannel2 := make(chan []byte)
	go pubnubInstance.Subscribe(channel, returnSubscribeChannel2, false)
	ParseSubscribeResponse(pubnubInstance, returnSubscribeChannel, t, channel, "already subscribed", "SubscriptionAlreadySubscribed", "")
}
// HereNow is a common method used by the tests TestHereNow, HereNowWithCipher, CustomUuid
// It subscribes to a pubnub channel and then
// makes a call to the herenow method of the pubnub api.
func HereNow(t *testing.T, cipherKey string, customUuid string, testName string) {
	pubnubInstance := pubnubMessaging.PubnubInit("demo", "demo", "", cipherKey, false, customUuid)

	channel := "testChannel"

	returnSubscribeChannel := make(chan []byte)
	go pubnubInstance.Subscribe(channel, returnSubscribeChannel, false)
	ParseSubscribeResponseForPresence(returnSubscribeChannel, channel)
	time.Sleep(500 * time.Millisecond)
	returnChannel := make(chan []byte)
	go pubnubInstance.HereNow(channel, returnChannel)
	ParseHereNowResponse(returnChannel, t, channel, customUuid, testName)
}
// TestSuccessCodeAndInfoForComplexMessage sends out a complex message to the pubnub channel
// The response is parsed and should match the 'sent' status.
// publishSuccessMessage and customstruct is defined in the common.go file
func TestSuccessCodeAndInfoForComplexMessage(t *testing.T) {
	pubnubInstance := pubnubMessaging.PubnubInit("demo", "demo", "", "", false, "")
	channel := "testChannel"

	customStruct := CustomStruct{
		Foo: "hi!",
		Bar: []int{1, 2, 3, 4, 5},
	}

	returnChannel := make(chan []byte)
	go pubnubInstance.Publish(channel, customStruct, returnChannel)

	ParsePublishResponse(returnChannel, t, channel, publishSuccessMessage, "SuccessCodeAndInfoForComplexMessage")
}
// Init asks the user the basic settings to initialize to the pubnub struct.
// Settings include the pubnub channel(s) to connect to.
// Ssl settings
// Cipher key
// Secret Key
// Custom Uuid
// Proxy details
//
// The method returns false if the channel name is not provided.
//
// returns: a bool, true if the user completed the initail settings.
func Init() (b bool) {
	fmt.Println("PubNub Api for go;", pubnubMessaging.VersionInfo())
	fmt.Println("Please enter the channel name(s). Enter multiple channels separated by comma.")
	reader := bufio.NewReader(os.Stdin)

	line, _, err := reader.ReadLine()
	if err != nil {
		fmt.Println(err)
	} else {
		_connectChannels = string(line)
		if strings.TrimSpace(_connectChannels) != "" {
			fmt.Println("Channel: ", _connectChannels)
			fmt.Println("Enable SSL. Enter y for Yes, n for No.")
			var enableSsl string
			fmt.Scanln(&enableSsl)

			if enableSsl == "y" || enableSsl == "Y" {
				_ssl = true
				fmt.Println("SSL enabled")
			} else {
				_ssl = false
				fmt.Println("SSL disabled")
			}

			fmt.Println("Please enter a CIPHER key, leave blank if you don't want to use this.")
			fmt.Scanln(&_cipher)
			fmt.Println("Cipher: ", _cipher)

			fmt.Println("Please enter a Custom UUID, leave blank for default.")
			fmt.Scanln(&_uuid)
			fmt.Println("UUID: ", _uuid)

			pubInstance := pubnubMessaging.PubnubInit("demo", "demo", "", _cipher, _ssl, _uuid)

			_pub = pubInstance

			SetupProxy()

			return true
		} else {
			fmt.Println("Channel cannot be empty.")
		}
	}
	return false
}
// TestPresence subscribes to the presence notifications on a pubnub channel and
// then subscribes to a pubnub channel. The test waits till we get a response from
// the subscribe call. The method that parses the presence response sets the global
// variable _endPresenceTestAsSuccess to true if the presence contains a join info
// on the channel and _endPresenceTestAsFailure is otherwise.
func TestPresence(t *testing.T) {
	customUuid := "customuuid"
	testName := "Presence"
	pubnubInstance := pubnubMessaging.PubnubInit("demo", "demo", "", "", false, customUuid)
	channel := "testForPresenceChannel"
	returnPresenceChannel := make(chan []byte)
	go SubscribeToPresence(channel, pubnubInstance, t, testName, customUuid, returnPresenceChannel)
	time.Sleep(500 * time.Millisecond)
	go SubscribeRoutine(channel, pubnubInstance)

	_endPresenceTestAsSuccess = false
	_endPresenceTestAsFailure = false

	for {
		if _endPresenceTestAsSuccess {
			fmt.Println("Test '" + testName + "': passed.")
			break
		} else if _endPresenceTestAsFailure {
			t.Error("Test '" + testName + "': failed.")
			break
		}
		time.Sleep(500 * time.Millisecond)
	}
}