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文件")
)

var connectionTimeout = time.Duration(500) * time.Millisecond

// 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,
	timeout int) (*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",
		Insecure: !w.sslVerify,
		Timeout:  time.Duration(timeout) * time.Second}.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,
		Insecure:    !w.sslVerify,
		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 {
	if transport, ok := goreq.DefaultTransport.(*http.Transport); ok {
		transport.TLSClientConfig = nil
	}
	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 &WebSession{
		AppID:          appID,
		AppSecret:      appSecret,
		TermID:         termID,
		BaseURL:        baseURL,
		DefaultTimeout: timeout,
		sslVerify:      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, 5)

	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, 5)
	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...)
}

// SetConnectionTimeout set global connection timeout
func SetConnectionTimeout(ms int) {
	connectionTimeout = time.Duration(ms) * time.Millisecond
}

// 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)
	goreq.SetConnectTimeout(connectionTimeout)
	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 != nil && r.Body != nil {
		defer r.Body.Close()
	}

	if r.StatusCode != 200 {
		log.Errorf("Request Error %v\n", r.StatusCode)
		err = fmt.Errorf("Request Error, StatusCode : %v", r.StatusCode)
		return
	}

	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
}
