// Copyright 2009 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 (
	"bytes"
	"crypto/md5"
	"encoding/binary"
	"http"
	"io"
	"strings"
)

/*
	Handler is an interface to a WebSocket.
	A trivial example server is:

	package main

	import (
		"http"
		"io"
		"websocket"
	)

	// Echo the data received on the Web Socket.
	func EchoServer(ws *websocket.Conn) {
		io.Copy(ws, ws);
	}

	func main() {
		http.Handle("/echo", websocket.Handler(EchoServer));
		err := http.ListenAndServe(":12345", nil);
		if err != nil {
			panic("ListenAndServe: " + err.String())
		}
	}
*/
type Handler func(*Conn)

/*
	Gets key number from Sec-WebSocket-Key<n>: field as described
 	in 5.2 Sending the server's opening handshake, 4.
*/
func getKeyNumber(s string) (r uint32) {
	// 4. Let /key-number_n/ be the digits (characters in the range
	// U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9)) in /key_1/,
	// interpreted as a base ten integer, ignoring all other characters
	// in /key_n/.
	r = 0
	for i := 0; i < len(s); i++ {
		if s[i] >= '0' && s[i] <= '9' {
			r = r*10 + uint32(s[i]) - '0'
		}
	}
	return
}

// ServeHTTP implements the http.Handler interface for a Web Socket
func (f Handler) ServeHTTP(c *http.Conn, req *http.Request) {
	rwc, buf, err := c.Hijack()
	if err != nil {
		panic("Hijack failed: " + err.String())
		return
	}
	// The server should abort the WebSocket connection if it finds
	// the client did not send a handshake that matches with protocol
	// specification.
	defer rwc.Close()

	if req.Method != "GET" {
		return
	}
	// HTTP version can be safely ignored.

	if strings.ToLower(req.Header["Upgrade"]) != "websocket" ||
		strings.ToLower(req.Header["Connection"]) != "upgrade" {
		return
	}

	// TODO(ukai): check Host
	origin, found := req.Header["Origin"]
	if !found {
		return
	}

	key1, found := req.Header["Sec-Websocket-Key1"]
	if !found {
		return
	}
	key2, found := req.Header["Sec-Websocket-Key2"]
	if !found {
		return
	}
	key3 := make([]byte, 8)
	if _, err := io.ReadFull(buf, key3); err != nil {
		return
	}

	location := "ws://" + req.Host + req.URL.RawPath

	// Step 4. get key number in Sec-WebSocket-Key<n> fields.
	keyNumber1 := getKeyNumber(key1)
	keyNumber2 := getKeyNumber(key2)

	// Step 5. get number of spaces in Sec-WebSocket-Key<n> fields.
	space1 := uint32(strings.Count(key1, " "))
	space2 := uint32(strings.Count(key2, " "))
	if space1 == 0 || space2 == 0 {
		return
	}

	// Step 6. key number must be an integral multiple of spaces.
	if keyNumber1%space1 != 0 || keyNumber2%space2 != 0 {
		return
	}

	// Step 7. let part be key number divided by spaces.
	part1 := keyNumber1 / space1
	part2 := keyNumber2 / space2

	// Step 8. let challenge to be concatination of part1, part2 and key3.
	challenge := make([]byte, 16)
	challengeBuf := bytes.NewBuffer(challenge)
	err = binary.Write(challengeBuf, binary.BigEndian, part1)
	if err != nil {
		return
	}
	err = binary.Write(challengeBuf, binary.BigEndian, part2)
	if err != nil {
		return
	}
	if n := copy(challenge[8:], key3); n != 8 {
		return
	}
	// Step 9. get MD5 fingerprint of challenge.
	h := md5.New()
	if _, err = h.Write(challenge); err != nil {
		return
	}
	response := h.Sum()

	// Step 10. send response status line.
	buf.WriteString("HTTP/1.1 101 WebSocket Protocol Handshake\r\n")
	// Step 11. send response headers.
	buf.WriteString("Upgrade: WebSocket\r\n")
	buf.WriteString("Connection: Upgrade\r\n")
	buf.WriteString("Sec-WebSocket-Location: " + location + "\r\n")
	buf.WriteString("Sec-WebSocket-Origin: " + origin + "\r\n")
	protocol, found := req.Header["Sec-WebSocket-Protocol"]
	if found {
		buf.WriteString("Sec-WebSocket-Protocol: " + protocol + "\r\n")
	}
	// Step 12. send CRLF.
	buf.WriteString("\r\n")
	// Step 13. send response data.
	buf.Write(response)
	if err := buf.Flush(); err != nil {
		return
	}
	ws := newConn(origin, location, protocol, buf, rwc)
	f(ws)
}


/*
 	Draft75Handler is an interface to a WebSocket based on
        (soon obsolete) draft-hixie-thewebsocketprotocol-75.
*/
type Draft75Handler func(*Conn)

// ServeHTTP implements the http.Handler interface for a Web Socket.
func (f Draft75Handler) ServeHTTP(c *http.Conn, req *http.Request) {
	if req.Method != "GET" || req.Proto != "HTTP/1.1" {
		c.WriteHeader(http.StatusBadRequest)
		io.WriteString(c, "Unexpected request")
		return
	}
	if req.Header["Upgrade"] != "WebSocket" {
		c.WriteHeader(http.StatusBadRequest)
		io.WriteString(c, "missing Upgrade: WebSocket header")
		return
	}
	if req.Header["Connection"] != "Upgrade" {
		c.WriteHeader(http.StatusBadRequest)
		io.WriteString(c, "missing Connection: Upgrade header")
		return
	}
	origin, found := req.Header["Origin"]
	if !found {
		c.WriteHeader(http.StatusBadRequest)
		io.WriteString(c, "missing Origin header")
		return
	}

	rwc, buf, err := c.Hijack()
	if err != nil {
		panic("Hijack failed: " + err.String())
		return
	}
	defer rwc.Close()
	location := "ws://" + req.Host + req.URL.RawPath

	// TODO(ukai): verify origin,location,protocol.

	buf.WriteString("HTTP/1.1 101 Web Socket Protocol Handshake\r\n")
	buf.WriteString("Upgrade: WebSocket\r\n")
	buf.WriteString("Connection: Upgrade\r\n")
	buf.WriteString("WebSocket-Origin: " + origin + "\r\n")
	buf.WriteString("WebSocket-Location: " + location + "\r\n")
	protocol, found := req.Header["Websocket-Protocol"]
	// canonical header key of WebSocket-Protocol.
	if found {
		buf.WriteString("WebSocket-Protocol: " + protocol + "\r\n")
	}
	buf.WriteString("\r\n")
	if err := buf.Flush(); err != nil {
		return
	}
	ws := newConn(origin, location, protocol, buf, rwc)
	f(ws)
}
