package gosh

import (
	"encoding/json"
	"io/ioutil"
	"net/http"
)

type RequestHelper struct {
	r *http.Request
}

func (r *RequestHelper) GetQuery(key string) string {
	return r.r.URL.Query().Get(key)
}

func (r *RequestHelper) GetBodyStr() string {
	body, err := ioutil.ReadAll(r.r.Body)
	if err != nil {
		return ""
	}
	return string(body)
}

func (r *RequestHelper) GetHeader(key string) string {
	return r.r.Header.Get(key)
}

func (r *RequestHelper) getJSONBody() (map[string]interface{}, error) {
	body, err := ioutil.ReadAll(r.r.Body)
	if err != nil {
		return nil, err
	}
	m := make(map[string]interface{})
	err = json.Unmarshal(body, &m)
	if err != nil {
		return nil, err
	}
	return m, nil
}

func (r *RequestHelper) getFormBody() (map[string]interface{}, error) {
	err := r.r.ParseForm()
	if err != nil {
		return nil, err
	}
	m := make(map[string]interface{})
	for key, values := range r.r.Form {
		if len(values) == 1 {
			m[key] = values[0]
		} else {
			m[key] = values
		}
	}
	return m, nil
}

func (r *RequestHelper) GetBody() map[string]interface{} {
	contentType := r.r.Header.Get("Content-Type")
	switch contentType {
	case "application/json":
		m, err := r.getJSONBody()
		if err != nil {
			return nil
		}
		return m
	case "application/x-www-form-urlencoded":
		m, err := r.getFormBody()
		if err != nil {
			return nil
		}
		return m
	}
	return nil
}

type ResponseHelper struct {
	w http.ResponseWriter
}

func (r *ResponseHelper) SetHeader(key, value string) {
	r.w.Header().Set(key, value)
}

func (r *ResponseHelper) WriteStr(s string) {
	r.w.Write([]byte(s))
}

func (r *ResponseHelper) WriteJSON(v interface{}) error {
	r.w.Header().Set("Content-Type", "application/json")
	data, err := json.Marshal(v)
	if err != nil {
		return err
	}
	_, err = r.w.Write(data)
	return err
}

func (r *ResponseHelper) Status(code int) {
	r.w.WriteHeader(code)
}

func (r *ResponseHelper) StatusOk() {
	r.w.WriteHeader(http.StatusOK)
}

func (r *ResponseHelper) StatusBadRequest() {
	r.w.WriteHeader(http.StatusBadRequest)
}

func (r *ResponseHelper) StatusNotFound() {
	r.w.WriteHeader(http.StatusNotFound)
}

func (r *ResponseHelper) StatusInternalServerError() {
	r.w.WriteHeader(http.StatusInternalServerError)
}

func (r *ResponseHelper) StatusForbidden() {
	r.w.WriteHeader(http.StatusForbidden)
}
