func TestConnection(t *testing.T) {

	ack_channel := make(chan state.Ack, 100)
	state_channel := make(chan state.StateResponse, 5)
	physics := processor.DefaultPhysics()
	factory := processor.NewFactory(&physics)
	manager := game.NewManager(physics.NewGameState(), state_channel, &factory)
	router := game.CommandRouter{GameManager: &manager, Acks: ack_channel}
	go manager.Start()

	reciever := network.UdpReceiver{
		Router:     router,
		Acks:       ack_channel,
		Responses:  state_channel,
		PortNumber: ":10002"}

	reciever.Run()
	conn, err := net.DialTimeout("udp", "127.0.0.1:10002", 1*time.Second)
	Convey("Test connect", t, func() {
		So(err, ShouldEqual, nil)
		So(conn, ShouldNotEqual, nil)
	})

	Convey("Test Connect command", t, func() {
		a := cmd.NewConnect("Dan")
		a.UniqueId = "abc123"
		message, err := json.Marshal(a)

		So(err, ShouldEqual, nil)

		i, error := conn.Write(message)

		So(i, ShouldBeGreaterThan, 0)
		So(error, ShouldEqual, nil)
	})

	Convey("Test State Responder", t, func() {
		reciever.Responses <- state.StateResponse{State: physics.NewGameState()}
		response := make([]byte, 2048)
		// read response
		conn.SetDeadline(time.Now().Add(2 * time.Second))
		n, err := bufio.NewReader(conn).Read(response)
		So(err, ShouldEqual, nil)
		So(string(response[:n]), ShouldEqual, "abc123")

		conn.SetDeadline(time.Now().Add(2 * time.Second))
		n, err = bufio.NewReader(conn).Read(response)
		So(err, ShouldEqual, nil)

		encoder := encoder.JsonEncoderDecoder{}

		_, encode_error := encoder.Decode(response[:n])
		So(encode_error, ShouldEqual, nil)

	})

}
func TestDecode(t *testing.T) {
	Convey("Decode", t, func() {
		formatter := encoder.JsonEncoderDecoder{Tag: "DecodeTest"}
		data := cmd.BaseCommand{Type: "GET", Subtype: "STATE", UniqueId: "ABC123"}
		buffer, error := json.Marshal(data)

		command, error := formatter.Decode(buffer)

		So(error, ShouldEqual, nil)
		So(command.Command().Type, ShouldEqual, "GET")
		So(command.Command().Subtype, ShouldEqual, "STATE")
		So(command.Command().UniqueId, ShouldEqual, "ABC123")
	})
}
func TestEncode(t *testing.T) {
	Convey("Encode", t, func() {
		formatter := encoder.JsonEncoderDecoder{Tag: "EncodeTest"}
		data := state.GameState{Val: "test Val"}

		decoded := state.GameState{}

		buffer, error := formatter.Encode(data)

		unmarshal_error := json.Unmarshal(buffer, &decoded)

		So(error, ShouldEqual, nil)
		So(unmarshal_error, ShouldEqual, nil)
		So(decoded.Val, ShouldEqual, "test Val")

	})
}
func TestDecodePowerup(t *testing.T) {
	Convey("Fire powerup", t, func() {
		formatter := encoder.JsonEncoderDecoder{Tag: "DecodeTest"}

		data := cmd.NewPowerup()
		data.UniqueId = "ABC123"
		buffer, error := json.Marshal(data)

		command, err := formatter.Decode(buffer)

		turn := command.(*cmd.PowerupCommand)

		So(error, ShouldEqual, nil)
		So(turn.Command().Type, ShouldEqual, cmd.Post)
		So(turn.Command().Subtype, ShouldEqual, cmd.POWERUP)
		So(err, ShouldEqual, nil)
		So(turn.Command().UniqueId, ShouldEqual, "ABC123")
	})
}
func TestDecodeConnect(t *testing.T) {
	Convey("Connect Decode", t, func() {
		formatter := encoder.JsonEncoderDecoder{Tag: "DecodeTest"}

		data := cmd.NewConnect("myname")
		data.UniqueId = "ABC123"
		buffer, error := json.Marshal(data)

		command, err := formatter.Decode(buffer)

		turn := command.(*cmd.ConnectCommand)

		So(error, ShouldEqual, nil)
		So(turn.Command().Type, ShouldEqual, cmd.Post)
		So(turn.Command().Subtype, ShouldEqual, cmd.Connect)
		So(err, ShouldEqual, nil)
		So(turn.Value, ShouldEqual, "myname")
		So(turn.Command().UniqueId, ShouldEqual, "ABC123")
	})
}
func TestDecodeTurn(t *testing.T) {
	Convey("Turn Decode", t, func() {
		formatter := encoder.JsonEncoderDecoder{Tag: "DecodeTest"}

		data := cmd.NewTurn(.2)
		data.UniqueId = "ABC123"
		buffer, error := json.Marshal(data)

		command, err := formatter.Decode(buffer)

		turn := command.(*cmd.TurnCommand)

		So(error, ShouldEqual, nil)
		So(turn.Command().Type, ShouldEqual, cmd.Post)
		So(turn.Command().Subtype, ShouldEqual, cmd.Turn)
		So(err, ShouldEqual, nil)
		So(turn.Value, ShouldAlmostEqual, .2, .000001)
		So(turn.Command().UniqueId, ShouldEqual, "ABC123")
	})
}