package swservice

import (
	"crypto/hmac"
	"crypto/sha1"
	"crypto/tls"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"sync"
	"time"

	"crypto/x509"

	log "github.com/Sirupsen/logrus"
	"github.com/franela/goreq"
)

var (
	// ErrBadCAPEM 错误的 CA 文件
	ErrBadCAPEM = errors.New("不正确的PEM文件")
)

// WebSession web session object
type WebSession struct {
	// AppId app id
	AppID string
	// TermId term id
	TermID string
	// Appsecret secret
	AppSecret string
	// BaseUrl base url
	BaseURL string
	// DefaultTimeout default time
	DefaultTimeout     int
	sessionKey         string
	sslVerify          bool
	httpConnectionPool sync.Pool
}

func safeGetJSONInt(value interface{}) int {
	if value == nil {
		return 0
	}
	s := fmt.Sprintf("%v", value)
	i, err := strconv.Atoi(s)
	if err != nil {
		return 0
	}
	return i
}

// ServiceResponse service response object
type ServiceResponse struct {
	// RetCode return code
	RetCode int
	// RetMsg return message
	RetMsg string
	// Result return data
	Result map[string]interface{}
}

// NewServiceResponseFromJSON parse json response data
func NewServiceResponseFromJSON(jsonData interface{}) *ServiceResponse {
	if jsonData == nil {
		return nil
	}
	res := &ServiceResponse{}
	res.Result = jsonData.(map[string]interface{})
	res.RetCode = safeGetJSONInt(res.Result["retcode"])
	res.RetMsg = res.GetStrValue("retmsg")
	return res
}

// GetIntValue get int value
func (r *ServiceResponse) GetIntValue(name string) int {
	return safeGetJSONInt(r.Result[name])
}

// GetStrValue get string value
func (r *ServiceResponse) GetStrValue(name string) string {
	s, ok := r.Result[name]
	if ok {
		return fmt.Sprintf("%v", s)
	}
	return ""
}

// GetInterfaceValue get value as interface
func (r *ServiceResponse) GetInterfaceValue(name string) interface{} {
	s, ok := r.Result[name]
	if ok {
		return s
	}
	return nil
}

// GetFloatValue get float value
func (r *ServiceResponse) GetFloatValue(name string) float64 {
	if s, ok := r.Result[name]; ok {
		t := fmt.Sprintf("%v", s)
		f, err := strconv.ParseFloat(t, 64)
		if err != nil {
			return 0.0
		}
		return f
	}
	return 0.0
}

// DoGet send GET request
func (w *WebSession) DoGet(uri string, params map[string]string) (*goreq.Response, error) {

	fullURL := w.BaseURL + uri

	vl := url.Values{}

	if params != nil {
		for k, v := range params {
			vl.Add(k, v)
		}
	}
	fullURL = fullURL + "?" + vl.Encode()
	return goreq.Request{Uri: fullURL, Method: "GET"}.Do()
}

// GetTimestamp get time stamp format 20160103133455
func (w *WebSession) GetTimestamp() string {
	t := time.Now()
	return fmt.Sprintf("%04d%02d%02d%02d%02d%02d", t.Year(), t.Month(), t.Day(),
		t.Hour(), t.Minute(), t.Second())
}

// SignWithKey sign with key
func (w *WebSession) SignWithKey(key, message string) string {
	mac := hmac.New(sha1.New, []byte(key))
	mac.Write([]byte(message))
	res := mac.Sum(nil)
	return hex.EncodeToString(res)
}

// Sign sign data
func (w *WebSession) Sign(message string) string {
	return w.SignWithKey(w.AppSecret, message)
}

func newTransport(baseurl string, sslVerify bool) *http.Transport {
	var transport http.Transport
	if strings.HasPrefix(baseurl, "https://") {
		var b bool
		if sslVerify {
			b = false
		} else {
			b = true
		}
		transport = http.Transport{MaxIdleConnsPerHost: 0,
			TLSClientConfig:     &tls.Config{InsecureSkipVerify: b},
			TLSHandshakeTimeout: time.Duration(1) * time.Second,
			Dial: func(network, addr string) (net.Conn, error) {
				defaultTimeout := time.Duration(1) * time.Second
				return net.DialTimeout(network, addr, defaultTimeout)
			}}
	} else if strings.HasPrefix(baseurl, "http://") {
		transport = http.Transport{MaxIdleConnsPerHost: 0,
			Dial: func(network, addr string) (net.Conn, error) {
				defaultTimeout := time.Duration(1) * time.Second
				return net.DialTimeout(network, addr, defaultTimeout)
			}}
	}
	log.Debugf("创建新连接")
	return &transport
}

// DoPost send POST request
func (w *WebSession) DoPost(uri string, param map[string]string) (*goreq.Response, error) {
	param["app_id"] = w.AppID
	param["term_id"] = w.TermID
	param["sign_method"] = "HMAC"
	param["session_key"] = w.sessionKey
	ts := w.GetTimestamp()
	param["timestamp"] = ts
	param["sign"] = w.Sign(w.AppID + w.TermID + w.sessionKey + ts)

	fullURL := w.BaseURL + uri
	data, err := json.Marshal(param)
	if err != nil {
		return nil, err
	}
	var r *goreq.Response
	r, err = goreq.Request{
		Uri:         fullURL,
		Method:      "POST",
		ContentType: "application/json",
		Body:        data,
		Timeout:     time.Duration(3) * time.Second}.Do()
	if err != nil || r.StatusCode != 200 {
		log.Errorf("Status=%v, err=%v", r, err)
	}
	return r, err
}

// Auth authorization
func (w *WebSession) Auth() error {
	token, err := w.getAuthToken()
	if err != nil {
		return err
	}
	err = w.getAppAccessKey(token)
	if err != nil {
		return err
	}
	return nil
}

// NewSession new session object
func NewSession(appid, appsecret, termid, baseurl string, timeout int, sslVerify bool) *WebSession {
	return &WebSession{
		AppID:          appid,
		AppSecret:      appsecret,
		TermID:         termid,
		BaseURL:        baseurl,
		DefaultTimeout: timeout,
		sslVerify:      sslVerify,
		httpConnectionPool: sync.Pool{New: func() interface{} {
			return newTransport(baseurl, sslVerify)
		}}}
}

// NewSessionWithCA new session ca
func NewSessionWithCA(appID, appSecret, termID, baseURL string,
	timeout int, ca []byte) (*WebSession, error) {
	certs := x509.NewCertPool()
	if !certs.AppendCertsFromPEM(ca) {
		return nil, ErrBadCAPEM
	}
	if transport, ok := goreq.DefaultTransport.(*http.Transport); ok {
		transport.TLSClientConfig = &tls.Config{RootCAs: certs}
	}

	return NewSession(appID, appSecret, termID, baseURL, timeout, true), nil
}

func (w *WebSession) getAuthToken() (string, error) {
	type FormJSON struct {
		AppID       string `json:"app_id"`
		TermID      string `json:"term_id"`
		AccessToken string `json:"access_token"`
	}

	uri := fmt.Sprintf("/authservice/getauth/%v/getaccesstoken", w.AppID)

	params := make(map[string]string)
	params["term_id"] = w.TermID
	r, err := w.DoGet(uri, params)

	if err != nil {
		return "", err
	}
	if r.StatusCode != 200 {
		return "", errors.New("请求失败")
	}

	body, err := ioutil.ReadAll(r.Body)
	defer r.Body.Close()

	s := &FormJSON{}
	err = json.Unmarshal(body, &s)
	if err != nil {
		log.Errorf("json unmarshal err %v", err)
		return "", errors.New("解析失败")
	}
	return s.AccessToken, nil
}

func (w *WebSession) getAppAccessKey(token string) error {
	type FormJSON struct {
		AppID      string `json:"app_id"`
		TermID     string `json:"term_id"`
		SessionKey string `json:"session_key"`
		CardKey    string `json:"card_key"`
	}

	uri := fmt.Sprintf("/authservice/getauth/%v", w.AppID)

	params := make(map[string]string)
	params["term_id"] = w.TermID
	params["access_token"] = token
	params["timestamp"] = w.GetTimestamp()
	params["v"] = "1"
	params["sign"] = w.Sign(token + params["timestamp"])
	params["sign_method"] = "HMAC"

	r, err := w.DoGet(uri, params)
	if r != nil {
		defer r.Body.Close()
	}
	if err != nil {
		log.Errorf("err = %v\n", err)
		return err
	}
	if r.StatusCode != 200 {
		log.Errorf(" errcode = %v\n", r.StatusCode)
		return fmt.Errorf("code %v", r.StatusCode)
	}

	body, err := ioutil.ReadAll(r.Body)

	s := &FormJSON{}
	err = json.Unmarshal(body, &s)
	if err != nil {
		log.Errorf("json unmarshal err %v", err)
		return err
	}
	w.sessionKey = s.SessionKey
	return nil
}

// CallYKTApi call ykt api function
func (w *WebSession) CallYKTApi(request *MessageWriter) (*MessageReader, error) {
	callData := request.Serialize()
	params := make(map[string]string)
	params["funcdata"] = callData
	r, err := w.DoPost("/ecardservice/ecardapi", params)

	if r != nil {
		defer r.Body.Close()
	}
	if err != nil {
		log.Errorf(" err = %v\n", err)
		return nil, err
	}

	if r.StatusCode != 200 {
		return nil, fmt.Errorf("Request StatusCode:%v", r.StatusCode)
	}

	body, err := ioutil.ReadAll(r.Body)
	return NewMessageReader(body), nil
}

// CallService call epay service
func (w *WebSession) CallService(path string, params map[string]interface{},
	signField []string, timeout int) (response *ServiceResponse, err error) {

	return w.CallService2(path, params, timeout, signField...)
}

// CallService2 call epay service
func (w *WebSession) CallService2(path string, params map[string]interface{}, timeout int,
	signField ...string) (response *ServiceResponse, err error) {
	err = nil
	params["app_id"] = w.AppID
	params["term_id"] = w.TermID
	ts := w.GetTimestamp()
	params["timestamp"] = ts

	vl := &url.Values{}
	for k, v := range params {
		vl.Set(k, fmt.Sprintf("%v", v))
	}

	signData := ""
	for _, k := range signField {
		if v, ok := params[k]; ok {
			signData += fmt.Sprintf("%v", v)
		}
	}
	signData += ts + w.sessionKey
	vl.Set("sign_method", "HMAC")
	log.Debugf("Sign: key[%v] data[%v]\n", w.sessionKey, signData)
	vl.Set("sign", w.SignWithKey(w.AppSecret, signData))

	fullURL := w.BaseURL + path
	log.Debugf("CallService: %v\n", fullURL)
	var r *goreq.Response
	r, err = goreq.Request{
		Uri:         fullURL,
		Accept:      "application/json",
		ContentType: "application/x-www-form-urlencoded",
		Method:      "POST",
		Timeout:     time.Duration(timeout) * time.Second,
		Body:        vl.Encode()}.Do()
	if err != nil {
		log.Errorf("Status=%v, err=%v", r, err)
		return
	}
	if r.StatusCode != 200 {
		log.Errorf("Request Error %v\n", r.StatusCode)
		err = fmt.Errorf("Request Error, StatusCode : %v", r.StatusCode)
		return
	}
	if r.Body != nil {
		defer r.Body.Close()
	}
	body, err := ioutil.ReadAll(r.Body)
	var s interface{}
	err = json.Unmarshal(body, &s)
	if err != nil {
		log.Errorf("json unmarshal err %v", err)
		return
	}
	response = NewServiceResponseFromJSON(s)
	return
}
