// 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 (
	"bufio"
	"crypto/tls"
	"io"
	"net"
	"net/url"
)

// DialError is an error that occurs while dialling a websocket server.
type DialError struct {
	*Config
	Err error
}

func (e *DialError) Error() string {
	return "websocket.Dial " + e.Config.Location.String() + ": " + e.Err.Error()
}

// NewConfig creates a new WebSocket config for client connection.
func NewConfig(server, origin string) (config *Config, err error) {
	config = new(Config)
	config.Version = ProtocolVersionHybi13
	config.Location, err = url.ParseRequest(server)
	if err != nil {
		return
	}
	config.Origin, err = url.ParseRequest(origin)
	if err != nil {
		return
	}
	return
}

// NewClient creates a new WebSocket client connection over rwc.
func NewClient(config *Config, rwc io.ReadWriteCloser) (ws *Conn, err error) {
	br := bufio.NewReader(rwc)
	bw := bufio.NewWriter(rwc)
	switch config.Version {
	case ProtocolVersionHixie75:
		err = hixie75ClientHandshake(config, br, bw)
	case ProtocolVersionHixie76, ProtocolVersionHybi00:
		err = hixie76ClientHandshake(config, br, bw)
	case ProtocolVersionHybi08, ProtocolVersionHybi13:
		err = hybiClientHandshake(config, br, bw)
	default:
		err = ErrBadProtocolVersion
	}
	if err != nil {
		return
	}
	buf := bufio.NewReadWriter(br, bw)
	switch config.Version {
	case ProtocolVersionHixie75, ProtocolVersionHixie76, ProtocolVersionHybi00:
		ws = newHixieClientConn(config, buf, rwc)
	case ProtocolVersionHybi08, ProtocolVersionHybi13:
		ws = newHybiClientConn(config, buf, rwc)
	}
	return
}

/*
Dial opens a new client connection to a WebSocket.

A trivial example client:

	package main

	import (
		"log"
		"net/http"
		"strings"
		"websocket"
	)

	func main() {
		origin := "http://localhost/"
		url := "ws://localhost/ws" 
		ws, err := websocket.Dial(url, "", origin)
		if err != nil {
			log.Fatal(err)
		}
		if _, err := ws.Write([]byte("hello, world!\n")); err != nil {
			log.Fatal(err)
		}
		var msg = make([]byte, 512);
		if n, err := ws.Read(msg); err != nil {
			log.Fatal(err)
		}
		// use msg[0:n]
	}
*/
func Dial(url_, protocol, origin string) (ws *Conn, err error) {
	config, err := NewConfig(url_, origin)
	if err != nil {
		return nil, err
	}
	return DialConfig(config)
}

// DialConfig opens a new client connection to a WebSocket with a config.
func DialConfig(config *Config) (ws *Conn, err error) {
	var client net.Conn
	if config.Location == nil {
		return nil, &DialError{config, ErrBadWebSocketLocation}
	}
	if config.Origin == nil {
		return nil, &DialError{config, ErrBadWebSocketOrigin}
	}
	switch config.Location.Scheme {
	case "ws":
		client, err = net.Dial("tcp", config.Location.Host)

	case "wss":
		client, err = tls.Dial("tcp", config.Location.Host, config.TlsConfig)

	default:
		err = ErrBadScheme
	}
	if err != nil {
		goto Error
	}

	ws, err = NewClient(config, client)
	if err != nil {
		goto Error
	}
	return

Error:
	return nil, &DialError{config, err}
}
