package util

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/juju/errors"
	"github.com/ngaut/log"
)

const (
	statusOK         = 200
	statusOtherError = 1
)

// Response represents message that returns to client
type Response struct {
	Code    int         `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data"`
}

// SuccessResponse formats http success response
func SuccessResponse(data interface{}) *Response {
	return &Response{
		Code: statusOK,
		Data: data,
	}
}

// ErrResponse response http error
func ErrResponse(err string) *Response {
	return &Response{
		Code:    statusOtherError,
		Message: err,
	}
}

// ErrResponsef formats http error
func ErrResponsef(format string, args ...interface{}) *Response {
	return &Response{
		Code:    statusOtherError,
		Message: fmt.Sprintf(format, args...),
	}
}

// ErrResponseWithData formats http error with other dagta
func ErrResponseWithData(message string, data interface{}) *Response {
	return &Response{
		Code:    statusOtherError,
		Message: message,
		Data:    data,
	}
}

// ExtractResponse extract response from api
func ExtractResponse(data []byte) ([]byte, error) {
	respData := &Response{}
	if err := json.Unmarshal(data, respData); err != nil {
		return nil, errors.Trace(err)
	}

	if respData.Code != http.StatusOK {
		d, err := json.Marshal(respData.Data)
		if err != nil {
			log.Errorf("marshal data failed %v", d)
		}

		return d, errors.New(respData.Message)
	}

	return json.Marshal(respData.Data)
}
