// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package websocket

import (
	"bufio"
	"bytes"
	"fmt"
	"http"
	"os"
	"strings"
	"testing"
	"url"
)

// Test the getChallengeResponse function with values from section
// 5.1 of the specification steps 18, 26, and 43 from
// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00
func TestHixie76Challenge(t *testing.T) {
	var part1 uint32 = 777007543
	var part2 uint32 = 114997259
	key3 := []byte{0x47, 0x30, 0x22, 0x2D, 0x5A, 0x3F, 0x47, 0x58}
	expected := []byte("0st3Rl&q-2ZU^weu")

	response, err := getChallengeResponse(part1, part2, key3)
	if err != nil {
		t.Errorf("getChallengeResponse: returned error %v", err)
		return
	}
	if !bytes.Equal(expected, response) {
		t.Errorf("getChallengeResponse: expected %q got %q", expected, response)
	}
}

func TestHixie76ClientHandshake(t *testing.T) {
	b := bytes.NewBuffer([]byte{})
	bw := bufio.NewWriter(b)
	br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Origin: http://example.com
Sec-WebSocket-Location: ws://example.com/demo
Sec-WebSocket-Protocol: sample

8jKS'y:G*Co,Wxa-`))

	var err os.Error
	config := new(Config)
	config.Location, err = url.ParseRequest("ws://example.com/demo")
	if err != nil {
		t.Fatal("location url", err)
	}
	config.Origin, err = url.ParseRequest("http://example.com")
	if err != nil {
		t.Fatal("origin url", err)
	}
	config.Protocol = append(config.Protocol, "sample")
	config.Version = ProtocolVersionHixie76

	config.handshakeData = map[string]string{
		"key1":    "4 @1  46546xW%0l 1 5",
		"number1": "829309203",
		"key2":    "12998 5 Y3 1  .P00",
		"number2": "259970620",
		"key3":    "^n:ds[4U",
	}
	err = hixie76ClientHandshake(config, br, bw)
	if err != nil {
		t.Errorf("handshake failed: %v", err)
	}
	req, err := http.ReadRequest(bufio.NewReader(b))
	if err != nil {
		t.Errorf("read request: %v", err)
	}
	if req.Method != "GET" {
		t.Errorf("request method expected GET, but got %q", req.Method)
	}
	if req.RawURL != "/demo" {
		t.Errorf("request path expected /demo, but got %q", req.RawURL)
	}
	if req.Proto != "HTTP/1.1" {
		t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto)
	}
	if req.Host != "example.com" {
		t.Errorf("request Host expected example.com, but got %v", req.Host)
	}
	var expectedHeader = map[string]string{
		"Connection":             "Upgrade",
		"Upgrade":                "WebSocket",
		"Origin":                 "http://example.com",
		"Sec-Websocket-Key1":     config.handshakeData["key1"],
		"Sec-Websocket-Key2":     config.handshakeData["key2"],
		"Sec-WebSocket-Protocol": config.Protocol[0],
	}
	for k, v := range expectedHeader {
		if req.Header.Get(k) != v {
			t.Errorf(fmt.Sprintf("%s expected %q but got %q", k, v, req.Header.Get(k)))
		}
	}
}

func TestHixie76ServerHandshake(t *testing.T) {
	config := new(Config)
	handshaker := &hixie76ServerHandshaker{Config: config}
	br := bufio.NewReader(strings.NewReader(`GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1  .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U`))
	req, err := http.ReadRequest(br)
	if err != nil {
		t.Fatal("request", err)
	}
	code, err := handshaker.ReadHandshake(br, req)
	if err != nil {
		t.Errorf("handshake failed: %v", err)
	}
	if code != http.StatusSwitchingProtocols {
		t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code)
	}
	b := bytes.NewBuffer([]byte{})
	bw := bufio.NewWriter(b)

	err = handshaker.AcceptHandshake(bw)
	if err != nil {
		t.Errorf("handshake response failed: %v", err)
	}
	expectedResponse := strings.Join([]string{
		"HTTP/1.1 101 WebSocket Protocol Handshake",
		"Upgrade: WebSocket",
		"Connection: Upgrade",
		"Sec-WebSocket-Origin: http://example.com",
		"Sec-WebSocket-Location: ws://example.com/demo",
		"Sec-WebSocket-Protocol: sample",
		"", ""}, "\r\n") + "8jKS'y:G*Co,Wxa-"
	if b.String() != expectedResponse {
		t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
	}
}

func TestHixie76SkipLengthFrame(t *testing.T) {
	b := []byte{'\x80', '\x01', 'x', 0, 'h', 'e', 'l', 'l', 'o', '\xff'}
	buf := bytes.NewBuffer(b)
	br := bufio.NewReader(buf)
	bw := bufio.NewWriter(buf)
	config := newConfig(t, "/")
	ws := newHixieConn(config, bufio.NewReadWriter(br, bw), nil, nil)
	msg := make([]byte, 5)
	n, err := ws.Read(msg)
	if err != nil {
		t.Errorf("Read: %v", err)
	}
	if !bytes.Equal(b[4:9], msg[0:n]) {
		t.Errorf("Read: expected %q got %q", b[4:9], msg[0:n])
	}
}

func TestHixie76SkipNoUTF8Frame(t *testing.T) {
	b := []byte{'\x01', 'n', '\xff', 0, 'h', 'e', 'l', 'l', 'o', '\xff'}
	buf := bytes.NewBuffer(b)
	br := bufio.NewReader(buf)
	bw := bufio.NewWriter(buf)
	config := newConfig(t, "/")
	ws := newHixieConn(config, bufio.NewReadWriter(br, bw), nil, nil)
	msg := make([]byte, 5)
	n, err := ws.Read(msg)
	if err != nil {
		t.Errorf("Read: %v", err)
	}
	if !bytes.Equal(b[4:9], msg[0:n]) {
		t.Errorf("Read: expected %q got %q", b[4:9], msg[0:n])
	}
}

func TestHixie76ClosingFrame(t *testing.T) {
	b := []byte{0, 'h', 'e', 'l', 'l', 'o', '\xff'}
	buf := bytes.NewBuffer(b)
	br := bufio.NewReader(buf)
	bw := bufio.NewWriter(buf)
	config := newConfig(t, "/")
	ws := newHixieConn(config, bufio.NewReadWriter(br, bw), nil, nil)
	msg := make([]byte, 5)
	n, err := ws.Read(msg)
	if err != nil {
		t.Errorf("read: %v", err)
	}
	if !bytes.Equal(b[1:6], msg[0:n]) {
		t.Errorf("Read: expected %q got %q", b[1:6], msg[0:n])
	}
	n, err = ws.Read(msg)
	if err != os.EOF {
		t.Errorf("read: %v", err)
	}
}
