package customization

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"github.com/xxtea/xxtea-go/xxtea"
	"netease_control_center/globals"
	"netease_control_center/interfaces/http"
	"netease_control_center/interfaces/log"
	"strconv"
	"time"
)

var (
	isFirst = true
)

const (
	telecom_url = "http://kd.zjjt.hl.zjip.com:9210/device/report"
)

var (
	telecom_vui = "本设备限在电信宽带网下使用,请切换网络重试。"
)

type TelecomReqBody struct {
	AppId     string `json:"appId"`
	Version   string `json:"version"`
	TimeStamp string `json:"timeStamp"`
	Device    string `json:"device"`
	Sign      string `json:"sign"`
	appSecret string `json:"-"`
}

/*
状态码(code) 状态描述(desc)
0 成功
1 设备使用非电信网络,不可以使用
2 黑名单设备
20 数据解密失败
21 appId 非法
22 接口版本号匹配失败
23 签名非法
99 平台内部错误
*/
type TelecomRspBody struct {
	Code      int    `json:"code"`
	Desc      string `json:"desc"`
	TimeStamp string `json:"timestamp"`
	Err       error  `json:"-"`
}

func (this *TelecomReqBody) Init() {
	var deviceInfo TelecomDeviceInfo
	now := time.Now()

	this.AppId = "5772415034"
	this.appSecret = "d89ef03a54cf42a3b514a58151ab9b9a"
	this.Version = "v1.0"
	this.TimeStamp = strconv.FormatInt(now.Unix()*1000, 10)

	deviceInfo.Ip = globals.WifiIp
	deviceInfo.Mac = globals.WifiMac
	deviceInfo.Sn = globals.CPU_ID
	deviceInfo.Manufactor = "Netease"
	deviceInfo.Name = globals.BTNAME
	deviceInfo.Model = *globals.Hv
	deviceInfo.Version = *globals.GitTag
	// 2006-01-02 15:04:05.999999999 -0700 MST
	deviceInfo.RefreshTime = now.Format("20060102150405")
	if isFirst {
		deviceInfo.RefreshState = "0"
	} else {
		deviceInfo.RefreshState = "1"
	}
	deviceInfo.SubDeviceData = []TelecomSubDevice{}

	if data, err := json.Marshal(deviceInfo); err == nil {
		log.Println(log.DebugLog, "dev:", string(data))
		this.Device = TelecomEncodeContent(data, this.appSecret)
	}

	this.Sign = TelecomSingnature(this.AppId+this.Version+this.TimeStamp, this.appSecret)
}

func (this TelecomReqBody) ToJson() []byte {
	if data, err := json.Marshal(this); err == nil {
		return data
	}

	return []byte{}
}

func (this *TelecomReqBody) Post() (result TelecomRspBody) {
	log.Println(log.DebugLog, "Telecom post:", string(this.ToJson()))
	defer func() {
		if result.Err == nil {
			isFirst = false
			switch result.Code {
			case 2:
				telecom_vui = "设备状态异常,请拨打 10000 号反馈。"
			default:
				telecom_vui = "本设备限在电信宽带网下使用,请切换网络重试。"
			}
		}
		log.Printf(log.DebugLog, "Result:%+v\n", result)
	}()
	if rsp, err := http.GetDefaultClient().Post(telecom_url, "application/json", bytes.NewReader(this.ToJson())); err == nil {
		defer rsp.Body.Close()
		result.Err = json.NewDecoder(rsp.Body).Decode(&result)
	} else {
		log.Println(log.ErrorLog, "Post telecom err:", err)
		result.Err = err
	}
	return
}

type TelecomDeviceInfo struct {
	Ip            string             `json:"ip"`
	Mac           string             `json:"mac"`
	Sn            string             `json:"sn"`
	Manufactor    string             `json:"manufactor"`
	Name          string             `json:"name"`
	Model         string             `json:"model"`
	Version       string             `json:"version"`
	RefreshTime   string             `json:"refreshTime"`
	RefreshState  string             `json:"refreshState"`
	SubDeviceData []TelecomSubDevice `json:"subDeviceData"`
}

type TelecomSubDevice struct {
	Sn      string `json:"sn"`
	Name    string `json:"name"`
	Model   string `json:"model"`
	Version string `json:"version"`
}

func TelecomSingnature(content string, key string) string {
	mac := hmac.New(sha1.New, []byte(key))
	mac.Write([]byte(content))
	return fmt.Sprintf("%02X", mac.Sum(nil))
}

func TelecomEncodeContent(content []byte, key string) string {
	output := xxtea.Encrypt(content, []byte(key))
	return fmt.Sprintf("%02X", output)
}
