package git

/*
#include <git2.h>
#include <git2/sys/transport.h>

typedef struct {
    git_smart_subtransport parent;
    void *ptr;
} managed_smart_subtransport;

typedef struct {
    git_smart_subtransport_stream parent;
    void *ptr;
} managed_smart_subtransport_stream;

int _go_git_transport_register(const char *scheme);
int _go_git_transport_smart(git_transport **out, git_remote *owner);
void _go_git_setup_smart_subtransport(managed_smart_subtransport *t, void *ptr);
void _go_git_setup_smart_subtransport_stream(managed_smart_subtransport_stream *t, void *ptr);
*/
import "C"

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"reflect"
	"runtime"
	"unsafe"
)

type SmartService int

const (
	SmartServiceUploadpackLs  = C.GIT_SERVICE_UPLOADPACK_LS
	SmartServiceUploadpack    = C.GIT_SERVICE_UPLOADPACK
	SmartServiceReceivepackLs = C.GIT_SERVICE_RECEIVEPACK_LS
	SmartServiceReceivepack   = C.GIT_SERVICE_RECEIVEPACK
)

type SmartSubtransport interface {
	Action(url string, action SmartService) (SmartSubtransportStream, error)
	Close() error
	Free()
}

type SmartSubtransportStream interface {
	Read(buf []byte) (int, error)
	Write(buf []byte) error
	Free()
}

func RegisterManagedHttp() error {
	httpStr := C.CString("http")
	defer C.free(unsafe.Pointer(httpStr))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()
	ret := C._go_git_transport_register(httpStr)
	if ret != 0 {
		return MakeGitError(ret)
	}

	return nil
}

func RegisterManagedHttps() error {
	httpsStr := C.CString("https")
	defer C.free(unsafe.Pointer(httpsStr))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()
	ret := C._go_git_transport_register(httpsStr)
	if ret != 0 {
		return MakeGitError(ret)
	}

	return nil
}

type ManagedTransport struct {
	owner *C.git_transport

	client *http.Client
}

func (self *ManagedTransport) Action(url string, action SmartService) (SmartSubtransportStream, error) {
	if err := self.ensureClient(); err != nil {
		return nil, err
	}

	var req *http.Request
	var err error
	switch action {
	case SmartServiceUploadpackLs:
		req, err = http.NewRequest("GET", url+"/info/refs?service=git-upload-pack", nil)

	case SmartServiceUploadpack:
		req, err = http.NewRequest("POST", url+"/git-upload-pack", nil)
		if err != nil {
			break
		}

		req.Header["Content-Type"] = []string{"application/x-git-upload-pack-request"}

	case SmartServiceReceivepackLs:
		req, err = http.NewRequest("GET", url+"/info/refs?service=git-receive-pack", nil)

	case SmartServiceReceivepack:
		req, err = http.NewRequest("POST", url+"/info/refs?service=git-upload-pack", nil)
		if err != nil {
			break
		}

		req.Header["Content-Type"] = []string{"application/x-git-receive-pack-request"}
	default:
		err = errors.New("unknown action")
	}

	if err != nil {
		return nil, err
	}

	req.Header["User-Agent"] = []string{"git/2.0 (git2go)"}
	return newManagedHttpStream(self, req), nil
}

func (self *ManagedTransport) Close() error {
	self.client = nil
	return nil
}

func (self *ManagedTransport) Free() {
}

func (self *ManagedTransport) ensureClient() error {
	if self.client != nil {
		return nil
	}

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	var cpopts C.git_proxy_options
	if ret := C.git_transport_smart_proxy_options(&cpopts, self.owner); ret < 0 {
		return MakeGitError(ret)
	}

	var proxyFn func(*http.Request) (*url.URL, error)
	proxyOpts := proxyOptionsFromC(&cpopts)
	switch proxyOpts.Type {
	case ProxyTypeNone:
		proxyFn = nil
	case ProxyTypeAuto:
		proxyFn = http.ProxyFromEnvironment
	case ProxyTypeSpecified:
		parsedUrl, err := url.Parse(proxyOpts.Url)
		if err != nil {
			return err
		}

		proxyFn = http.ProxyURL(parsedUrl)
	}

	transport := &http.Transport{
		Proxy: proxyFn,
	}
	self.client = &http.Client{Transport: transport}

	return nil
}

type ManagedHttpStream struct {
	owner       *ManagedTransport
	req         *http.Request
	resp        *http.Response
	postBuffer  bytes.Buffer
	sentRequest bool
}

func newManagedHttpStream(owner *ManagedTransport, req *http.Request) *ManagedHttpStream {
	return &ManagedHttpStream{
		owner: owner,
		req:   req,
	}
}

func (self *ManagedHttpStream) Read(buf []byte) (int, error) {
	if !self.sentRequest {
		if err := self.sendRequest(); err != nil {
			return 0, err
		}
	}

	return self.resp.Body.Read(buf)
}

func (self *ManagedHttpStream) Write(buf []byte) error {
	// We write it all into a buffer and send it off when the transport asks
	// us to read.
	self.postBuffer.Write(buf)
	return nil
}

func (self *ManagedHttpStream) Free() {
	self.resp.Body.Close()
}

func (self *ManagedHttpStream) sendRequest() error {
	var resp *http.Response
	var err error
	var userName string
	var password string
	for {
		req := &http.Request{
			Method:        self.req.Method,
			URL:           self.req.URL,
			Header:        self.req.Header,
			Body:          ioutil.NopCloser(&self.postBuffer),
			ContentLength: int64(self.postBuffer.Len()),
		}

		req.SetBasicAuth(userName, password)
		resp, err = http.DefaultClient.Do(req)
		if err != nil {
			return err
		}

		if resp.StatusCode == http.StatusOK {
			break
		}

		if resp.StatusCode == http.StatusUnauthorized {
			resp.Body.Close()
			var cred *C.git_cred

			runtime.LockOSThread()
			defer runtime.UnlockOSThread()
			ret := C.git_transport_smart_credentials(&cred, self.owner.owner, nil, C.GIT_CREDTYPE_USERPASS_PLAINTEXT)

			if ret != 0 {
				return MakeGitError(ret)
			}

			if cred.credtype != C.GIT_CREDTYPE_USERPASS_PLAINTEXT {
				C.git_cred_free(cred)
				return fmt.Errorf("Unexpected credential type %d", cred.credtype)
			}
			ptCred := (*C.git_cred_userpass_plaintext)(unsafe.Pointer(cred))
			userName = C.GoString(ptCred.username)
			password = C.GoString(ptCred.password)
			C.git_cred_free(cred)

			continue
		}

		// Any other error we treat as a hard error and punt back to the caller
		resp.Body.Close()
		return fmt.Errorf("Unhandled HTTP error %s", resp.Status)
	}

	self.sentRequest = true
	self.resp = resp
	return nil
}

func setLibgit2Error(err error) C.int {
	cstr := C.CString(err.Error())
	defer C.free(unsafe.Pointer(cstr))
	C.giterr_set_str(C.GITERR_NET, cstr)

	if gitErr, ok := err.(*GitError); ok {
		return C.int(gitErr.Code)
	}

	return -1
}

//export httpAction
func httpAction(out **C.git_smart_subtransport_stream, t *C.git_smart_subtransport, url *C.char, action C.git_smart_service_t) C.int {
	transport, err := getSmartSubtransportInterface(t)
	if err != nil {
		return setLibgit2Error(err)
	}

	managed, err := transport.Action(C.GoString(url), SmartService(action))
	if err != nil {
		return setLibgit2Error(err)
	}

	stream := C.calloc(1, C.size_t(unsafe.Sizeof(C.managed_smart_subtransport_stream{})))
	managedPtr := pointerHandles.Track(managed)
	C._go_git_setup_smart_subtransport_stream(stream, managedPtr)

	*out = (*C.git_smart_subtransport_stream)(stream)
	return 0
}

//export httpClose
func httpClose(t *C.git_smart_subtransport) C.int {
	transport, err := getSmartSubtransportInterface(t)
	if err != nil {
		return setLibgit2Error(err)
	}

	if err := transport.Close(); err != nil {
		return setLibgit2Error(err)
	}

	return 0
}

//export httpFree
func httpFree(transport *C.git_smart_subtransport) {
	wrapperPtr := (*C.managed_smart_subtransport)(unsafe.Pointer(transport))
	pointerHandles.Untrack(wrapperPtr.ptr)
}

var errNoSmartSubtransport = errors.New("passed object does not implement SmartSubtransport")

func getSmartSubtransportInterface(_t *C.git_smart_subtransport) (SmartSubtransport, error) {
	wrapperPtr := (*C.managed_smart_subtransport)(unsafe.Pointer(_t))

	transport, ok := pointerHandles.Get(wrapperPtr.ptr).(SmartSubtransport)
	if !ok {
		return nil, errNoSmartSubtransport
	}

	return transport, nil
}

//export httpTransportCb
func httpTransportCb(out **C.git_transport, owner *C.git_remote, param unsafe.Pointer) C.int {
	return C._go_git_transport_smart(out, owner)
}

//export httpSmartSubtransportCb
func httpSmartSubtransportCb(out **C.git_smart_subtransport, owner *C.git_transport, param unsafe.Pointer) C.int {
	if out == nil {
		return -1
	}

	transport := C.calloc(1, C.size_t(unsafe.Sizeof(C.managed_smart_subtransport{})))
	managed := &ManagedTransport{owner: owner}
	managedPtr := pointerHandles.Track(managed)
	C._go_git_setup_smart_subtransport(transport, managedPtr)

	*out = (*C.git_smart_subtransport)(transport)
	return 0
}

var errNoSmartSubtransportStream = errors.New("passed object does not implement SmartSubtransportStream")

func getSmartSubtransportStreamInterface(_s *C.git_smart_subtransport_stream) (SmartSubtransportStream, error) {
	wrapperPtr := (*C.managed_smart_subtransport_stream)(unsafe.Pointer(_s))

	transport, ok := pointerHandles.Get(wrapperPtr.ptr).(SmartSubtransportStream)
	if !ok {
		return nil, errNoSmartSubtransportStream
	}

	return transport, nil
}

//export smartSubtransportRead
func smartSubtransportRead(s *C.git_smart_subtransport_stream, data *C.char, l C.size_t, read *C.size_t) C.int {
	stream, err := getSmartSubtransportStreamInterface(s)
	if err != nil {
		return setLibgit2Error(err)
	}

	var p []byte
	header := (*reflect.SliceHeader)(unsafe.Pointer(&p))
	header.Cap = int(l)
	header.Len = int(l)
	header.Data = uintptr(unsafe.Pointer(data))

	n, err := stream.Read(p)
	if err != nil {
		if err == io.EOF {
			*read = C.size_t(0)
			return 0
		}

		setLibgit2Error(err)
		return -1
	}

	*read = C.size_t(n)
	return 0
}

//export smartSubtransportWrite
func smartSubtransportWrite(s *C.git_smart_subtransport_stream, data unsafe.Pointer, l C.size_t) C.int {
	stream, err := getSmartSubtransportStreamInterface(s)
	if err != nil {
		return setLibgit2Error(err)
	}

	var p []byte
	header := (*reflect.SliceHeader)(unsafe.Pointer(&p))
	header.Cap = int(l)
	header.Len = int(l)
	header.Data = uintptr(data)

	if err := stream.Write(p); err != nil {
		return setLibgit2Error(err)
	}

	return 0
}

//export smartSubtransportFree
func smartSubtransportFree(s *C.git_smart_subtransport_stream) {
}
