package main

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"mime/multipart"
	"net/http"
	"net/http/httputil"
	"os"
)

//post a file to a url
func postFileForm(filename string, targetURL string, formFieldName string) (strJSON string, err error) {
	bodyBuf := &bytes.Buffer{}
	bodyWriter := multipart.NewWriter(bodyBuf)

	// this step is very important
	fileWriter, err := bodyWriter.CreateFormFile(formFieldName, filename)
	if err != nil {
		fmt.Println(err)
		return "", err
	}

	// open file handle
	fh, err := os.Open(filename)
	if err != nil {
		fmt.Println(err)
		return "", err
	}

	//iocopy
	_, err = io.Copy(fileWriter, fh)
	if err != nil {
		return "", err
	}

	contentType := bodyWriter.FormDataContentType()
	bodyWriter.Close()

	resp, err := http.Post(targetURL, contentType, bodyBuf)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	r, err := ioutil.ReadAll(resp.Body)
	strJSON = string(r)
	if err != nil {
		return "", err
	}
	fmt.Println(resp.Status)
	fmt.Println(string(strJSON))
	return strJSON, nil
}

func postJSON(jsonB []byte, targetURL string) (resp string, err error) {
	headers := map[string]string{}
	headers["Content-Type"] = "application/json"
	return postRAW(jsonB, targetURL, headers)
}

func postRAW(data []byte, targetURL string, headers map[string]string) (resp string, err error) {
	return httpRaw("POST", targetURL, data, headers)
}

func putRAW(data []byte, targetURL string, headers map[string]string) (resp string, err error) {
	return httpRaw("PUT", targetURL, data, headers)
}

func httpRaw(httpMethod, targetURL string, data []byte, headers map[string]string) (resp string, err error) {
	req, err := http.NewRequest(httpMethod, targetURL, bytes.NewBuffer(data))
	if err != nil {
		return
	}

	if headers != nil {
		for k, v := range headers {
			req.Header.Set(k, v)
		}
	}

	client := &http.Client{}
	r, err := client.Do(req)
	if err != nil {
		return
	}
	defer r.Body.Close()

	dump, err := httputil.DumpResponse(r, true)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("dump : %s", dump)

	b, _ := ioutil.ReadAll(r.Body)
	resp = string(b)
	log.Println(resp)

	return

}
