package ssh

import (
	"bufio"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"time"

	"golang.org/x/net/proxy"
)

// Dialer implements for SSH over HTTP Proxy.
type proxyDialer struct {
	proxy proxyInfo
	// forwarding Dialer
	forward proxy.Dialer
}

type proxyInfo struct {
	// HTTP Proxy host or host:port
	host string
	// HTTP Proxy scheme
	scheme string
	// An immutable encapsulation of username and password details for a URL
	userInfo *url.Userinfo
}

func newProxyInfo(host, scheme, username, password string) *proxyInfo {
	p := &proxyInfo{
		host:   host,
		scheme: scheme,
	}

	p.userInfo = url.UserPassword(username, password)

	if p.scheme == "" {
		p.scheme = "http"
	}

	return p
}

func (p *proxyInfo) url() *url.URL {
	return &url.URL{
		Scheme: p.scheme,
		User:   p.userInfo,
		Host:   p.host,
	}
}

func (p *proxyDialer) Dial(network, addr string) (net.Conn, error) {
	// Dial the proxy host
	c, err := p.forward.Dial(network, p.proxy.host)

	if err != nil {
		return nil, err
	}

	err = c.SetDeadline(time.Now().Add(15 * time.Second))
	if err != nil {
		return nil, err
	}

	// Generate request URL to host accessed through the proxy
	reqUrl := &url.URL{
		Scheme: "",
		Host:   addr,
	}

	// Create a request object using the CONNECT method to instruct the proxy server to tunnel a protocol other than HTTP.
	req, err := http.NewRequest("CONNECT", reqUrl.String(), nil)
	if err != nil {
		c.Close()
		return nil, err
	}

	// If http proxy requires authentication, configure settings for basic authentication.
	if p.proxy.userInfo.String() != "" {
		username := p.proxy.userInfo.Username()
		password, _ := p.proxy.userInfo.Password()
		req.SetBasicAuth(username, password)
		req.Header.Add("Proxy-Authorization", req.Header.Get("Authorization"))
	}

	// Do not close the connection after sending this request and reading its response.
	req.Close = false

	// Writes the request in the form expected by an HTTP proxy.
	err = req.Write(c)
	if err != nil {
		c.Close()
		return nil, err
	}

	res, err := http.ReadResponse(bufio.NewReader(c), req)

	if err != nil {
		res.Body.Close()
		c.Close()
		return nil, err
	}

	res.Body.Close()

	if res.StatusCode != http.StatusOK {
		c.Close()
		return nil, fmt.Errorf("Connection Error: StatusCode: %d", res.StatusCode)
	}

	return c, nil
}

// NewHttpProxyDialer generate Http Proxy Dialer
func newHttpProxyDialer(u *url.URL, forward proxy.Dialer) (proxy.Dialer, error) {
	var proxyUserName, proxyPassword string
	if u.User != nil {
		proxyUserName = u.User.Username()
		proxyPassword, _ = u.User.Password()
	}

	pd := &proxyDialer{
		proxy:   *newProxyInfo(u.Host, u.Scheme, proxyUserName, proxyPassword),
		forward: forward,
	}

	return pd, nil
}

// RegisterDialerType register schemes used by `proxy.FromURL`
func RegisterDialerType() {
	proxy.RegisterDialerType("http", newHttpProxyDialer)
	proxy.RegisterDialerType("https", newHttpProxyDialer)
}

// NewHttpProxyConn create a connection to connect through the proxy server.
func newHttpProxyConn(p *proxyInfo, targetAddr string) (net.Conn, error) {
	pd, err := proxy.FromURL(p.url(), proxy.Direct)

	if err != nil {
		return nil, err
	}

	proxyConn, err := pd.Dial("tcp", targetAddr)

	if err != nil {
		return nil, err
	}

	return proxyConn, err
}
