package controller

import (
	"context"
	"encoding/json"
	"expvar"
	"fmt"
	"github.com/julienschmidt/httprouter"
	"github.com/shirou/gopsutil/cpu"
	"github.com/shirou/gopsutil/host"
	"github.com/shirou/gopsutil/load"
	"github.com/shirou/gopsutil/mem"
	"github.com/shirou/gopsutil/process"
	"io/ioutil"
	"net"
	"net/http"
	"net/http/pprof"
	"netease_control_center/globals"
	"netease_control_center/interfaces/cserveraddr"
	http2 "netease_control_center/interfaces/http"
	"netease_control_center/interfaces/innerTask"
	"netease_control_center/interfaces/log"
	"netease_control_center/interfaces/schedule"
	"netease_control_center/interfaces/vui"
	"netease_control_center/interfaces/vui/cvui"
	"netease_control_center/modules/hardware/led_mcu"
	"netease_control_center/modules/hardware/mcu_leds/atservice"
	"netease_control_center/modules/player"
	"netease_control_center/modules/storage"
	"netease_control_center/modules/wifi"
	"netease_control_center/nembd"
	"netease_control_center/nembd/controller/adau1761"
	"netease_control_center/nembd/controller/micadc"
	"netease_control_center/utils"
	"netease_control_center/utils/customization"
	"netease_control_center/utils/glog"
	"netease_control_center/utils/ntp"
	"netease_control_center/utils/runtime-metrics"
	"os"
	"strconv"
	"strings"
	"sync/atomic"
	"time"
)

func BasicAuth(h httprouter.Handle, requiredUser, requiredPassword string) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
		// Get the Basic Authentication credentials
		user, password, hasAuth := r.BasicAuth()

		if hasAuth && user == requiredUser && password == requiredPassword {
			// Delegate request to the given handle
			h(w, r, ps)
		} else {
			// Request Basic Authentication otherwise
			w.Header().Set("WWW-Authenticate", "Basic realm=Restricted")
			http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
		}
	}
}

func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	fmt.Fprint(w, "Not protected!\n")
}

func Protected(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	fmt.Fprint(w, "Protected!\n")
}

func Post(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	fmt.Fprint(w, "Protected!\n")
}

func HTTPSERVER_WifiConfig(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	var ret struct {
		Code int    `json:"code"`
		Desc string `json:"desc"`
	}

	if data, err := ioutil.ReadAll(r.Body); err == nil {
		log.Println(log.DebugLog, "Get app:", string(data))
		var ssids globals.BtWifiParing
		if err = json.Unmarshal(data, &ssids); err == nil {
			if len(ssids.Ssid) == 0 || len(ssids.Account) == 0 {
				ret.Code = 1001
				ret.Desc = "wifi账号或者用户账号为空"
			} else if globals.CurBootState != globals.BootStage_WIFIPARING || globals.CurWifiParingMode != globals.WifiParingMode_AP {
				ret.Code = 1001
				ret.Desc = "当前不在wifi配对模式"
			} else {
				ret.Code = 1000
				ret.Desc = "即将开始连接wifi:" + ssids.Ssid
				go func() {
					time.Sleep(2 * time.Second)
					ssids.OrigString = string(data)
					ClearWifiChanAddWifi(ssids)
				}()

			}
		} else {
			ret.Code = 1001
			ret.Desc = err.Error()
		}
	} else {
		ret.Code = 1001
		ret.Desc = err.Error()
	}

	if data, dataerr := json.Marshal(ret); dataerr == nil {
		w.Write(data)
	}
	log.Println(log.DebugLog, "Return app:", ret)
}

func HTTPSERVER_Connect(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	var ret struct {
		Code   int    `json:"code"`
		Desc   string `json:"desc"`
		ErrMsg string `json:"err_msg"`
	}

	ret.Code = 1000
	if lastAPWifiParingErr != nil {
		ret.ErrMsg = lastAPWifiParingErr.Error()
	}
	ret.Desc = "netease ihw"

	if data, dataerr := json.Marshal(ret); dataerr == nil {
		w.Write(data)
	} else {
		log.Println(log.DebugLog, "json marshal err:", dataerr)
	}

	if globals.CurBootState == globals.BootStage_WIFIPARING && globals.CurWifiParingMode == globals.WifiParingMode_AP {
		player.SoundEffectPlayCmd(globals.CMD_SE_PLAY, vui.SoundNotice_Slianjiechenggong001.GetPath())
	}
	log.Println(log.DebugLog, "Jump into HTTPSERVER_Connect!")
}

func HTTPSERVER_HttpEnv(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	switch ps.ByName("mode") {
	//case "0":
	//	http2.ServerIp = http2.ServerIp_ONLINE
	//	fmt.Fprintln(w, "Change to online: ", http2.ServerIp)
	//	os.Remove(test.SERVER_IP_CFG_FILE)
	//	BroadChangeOnlineServer()
	//	goto _clearuuid
	//case "1":
	//http2.ServerIp = http2.ServerIp_TEST
	//	fmt.Fprintln(w, "Change to test: ", http2.ServerIp)
	//	if fd,err := os.Create(test.SERVER_IP_CFG_FILE); err == nil {
	//		fmt.Fprintln(w, "Create file successfully!")
	//		fd.Close()
	//	} else {
	//		fmt.Fprintln(w, "Create file fail:", err)
	//	}
	//	BroadChangeTestServer()
	//	goto _clearuuid

	case "0", "dev":
		cserveraddr.SetDevEnv(cserveraddr.DEVENV_DEVELOP)
		goto _clearuuid

	case "1", "test":
		cserveraddr.SetDevEnv(cserveraddr.DEVENV_TEST)
		goto _clearuuid

	case "2", "product":
		cserveraddr.SetDevEnv(cserveraddr.DEVENV_PUBLISH)
		goto _clearuuid

	case "3", "prerelease":
		cserveraddr.SetDevEnv(cserveraddr.DEVENV_PRERELEASE)
		goto _clearuuid

	case "999":
		fmt.Fprintln(w, "Get env:", cserveraddr.GetDevEnv())
		fmt.Fprintln(w, "Cur http: ", cserveraddr.GetServerAddr())
	default:
		fmt.Fprintln(w, "Unknow mode, do nothing!")
	}

	return

_clearuuid:
	storage.Config_set(globals.MODULE_CONTROLLER, globals.SQL_KEY_BINDUSER, "")
	storage.Config_set(globals.MODULE_CONTROLLER, globals.SQL_KEY_UUID, "")

	fmt.Fprintln(w, "New addr:", cserveraddr.GetServerAddr(), "New env:", cserveraddr.GetDevEnv())
	fmt.Fprintln(w, "Clear uuid and reboot 2s after!")

	go func() {
		time.Sleep(2 * time.Second)
		log.Printf(log.DebugLog, "begin to reboot....\n")
		nembd.ExecOutput("reboot")
	}()
}

func HTTPSERVER_ScheduleStatus(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	fmt.Fprintln(w, schedule.GetAllTaskStatus())
	fmt.Fprintln(w, schedule.GetAllPlayerStatus())
}

func LogFiles(r *httprouter.Router, path string, root http.FileSystem) {
	if len(path) < 10 || path[len(path)-10:] != "/*filepath" {
		panic("path must end with /*filepath in path '" + path + "'")
	}

	fileServer := http.FileServer(root)

	r.GET(path, func(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
		glog.Flush()
		req.URL.Path = ps.ByName("filepath")
		fileServer.ServeHTTP(w, req)
	})
}

func HTTPSERVER_JSON(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	cmd := ps.ByName("args")
	switch cmd {
	case "systeminfo":
		data := runtime_metrics.GetNeteaseDeviceInfo()
		w.Write(data)

	default:
		var tmp struct {
			Cmd  string `json:"unknowcmd"`
			Time time.Time
		}

		tmp.Cmd = cmd
		tmp.Time = time.Now()
		if data, err := json.Marshal(tmp); err == nil {
			w.Write(data)
		}
	}
}
func HTTPSERVER_test(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	defer func() {
		if err := recover(); err != nil {
			fmt.Fprintln(w, "Catch a err: ", err)
		}
	}()

	if data, err := json.Marshal(ps); err == nil {
		fmt.Fprintln(w, "Get arg:", string(data))
	}

	argstring := ps.ByName("args")
	args := strings.Split(argstring, "/")
	fmt.Fprintf(w, "args: %+v\n", args)
	if len(args) > 0 {
		args = args[1:]
	}

	switch args[0] {
	case "fespa_set":
		switch args[1] {
		case "once":
			Nduilite_fespa_set_arg(true)

		case "many":
			go func() {
				i := 0
				for {
					Nduilite_fespa_set_arg(true)
					time.Sleep(time.Millisecond * 650)
					log.Println(log.DebugLog, "Re init speech sdk!", i)
					i++
				}
			}()
		}

	case "pingaddrs":
		for i := 0; i < 100; i++ {
			fmt.Fprintln(w, GetRandomPingAddr())
		}

	case "iotwifi":
		schedule.SendSCmd(schedule.SCMD_SuperTask_Enter_IOT_WifiParing)
		fmt.Fprintf(w, "jump in iotwifi. Send SCMD_SuperTask_Enter_IOT_WifiParing")

	case "chinatelecom":
		customization.ChinaTelecomReport()

	case "bug3497":
		go func() {
			for i := 0; i < 5000; i++ {
				led_mcu.DirectLedControl(atservice.GUIDE_EFFECT_ID_EXEC_CMD, atservice.GUIDE_ACTION_START, 0, []byte{})
				schedule.PlayNoticeSync(globals.AdSrcType_TTS, fmt.Sprintf("测试第%d次, PV1-3497", i), globals.CONST_AUDIO_ID, false, nil)
				led_mcu.DirectLedControl(atservice.GUIDE_EFFECT_ID_EXEC_CMD, atservice.GUIDE_ACTION_STOP, 0, []byte{})
			}
		}()

	case "startmic":
		micCronStart()

	case "endmic":
		micCronEnd()

	case "updatemic":
		UpdateMicStatus(true)

	case "setmic":
		start_hour, _ := strconv.Atoi(args[1])
		start_min, _ := strconv.Atoi(args[2])
		end_hour, _ := strconv.Atoi(args[3])
		end_min, _ := strconv.Atoi(args[4])
		Aon, _ := strconv.Atoi(args[5])
		lon, _ := strconv.Atoi(args[6])

		Aswitch := false
		lswitch := false

		if Aon == 1 {
			Aswitch = true
		}

		if lon == 1 {
			lswitch = true
		}

		micControl = CronMic{MainSwitch: Aswitch, LightSwitch: lswitch, StartTimeStamp: time.Date(2018, 1, 1, start_hour, start_min, 0, 0, ChinaLocation).Unix() * 1000,
			EndTimeStamp: time.Date(2018, 1, 1, end_hour, end_min, 0, 0, ChinaLocation).Unix() * 1000}

		fmt.Fprintf(w, "%+v\n", micControl)
	case "testvui":
		vuicount := int32(0)
		for i := 0; i < 1000; i++ {
			x := i
			go func() {
				for z := 0; z <= 1000; z++ {
					vui.SoundNotice_Stixing001.GetPath()
					fmt.Println(x, "exit!", atomic.AddInt32(&vuicount, 1))
				}
			}()
		}
	case "testapstatus":
		for i := wifi.APSTATUS(0); i <= wifi.APSTATUS(5000); i++ {
			wifi.SetAPstatus(i)
			if wifi.GetAPstatus() != i {
				log.Println(log.ErrorLog, "test error:", i)
				fmt.Fprintln(w, "test error:", i)
			}
		}

	case "testserver":
		sum, _ := strconv.Atoi(args[1])
		ts := time.Now()
		for i := 0; i < sum; i++ {
			var req http2.HttpReqGetTimeStamp
			var rsp *http2.HttpRspGetTimeStamp
			if code, _, err := http2.HttpPostAuto(req, &rsp); err != nil && code != 1000 {
				fmt.Fprintln(w, i, code, err)
				fmt.Println(i)
			}
		}
		fmt.Fprintln(w, "Coast:", time.Now().Sub(ts))

	case "testserver2":
		sum, _ := strconv.Atoi(args[1])
		ts := time.Now()
		for i := 0; i < sum; i++ {
			if _, _, _, err := http2.GetWeatherInfo(); err != nil {
				fmt.Fprintln(w, i, err)
			}
		}
		fmt.Fprintln(w, "Coast:", time.Now().Sub(ts))

	case "testntp":
		tmp := ntp.TestNtpServer()
		fmt.Fprintln(w, tmp)

	case "httpcaltime":
		var req http2.HttpReqGetTimeStamp
		var rsp http2.HttpRspGetTimeStamp
		if code, _, httperr := http2.HttpPostAuto(req, &rsp); code == 1000 && httperr == nil {
			log.Println(log.DebugLog, "http req server success!")
			fmt.Fprintf(w, "cal success, code:%+v, rsp:%+v\n", code, rsp)
		} else {
			fmt.Fprintf(w, "cal time fail, code:%+v, error:%+v\n", code, httperr)
		}

	case "caltime":
		server, err := ntp.CalTimeWithDefaultServers()
		fmt.Fprintln(w, server, err, time.Now())

	case "seteq":
		eq, _ := strconv.Atoi(args[1])
		globals.SetEq(globals.ADAU1761_EQ(eq))
		fmt.Fprintln(w, "Set eq:", eq)

	case "testhttpinit":
		err, code := FinalInitUUID(true, globals.BindUser)
		fmt.Fprintln(w, err, code)

	case "systeminfo":
		output, outputerr := nembd.ExecOutput("/bin/sh", "-c", "/bin/dump_mem.sh")
		fmt.Fprintln(w, outputerr, output)
		output, outputerr = nembd.ExecOutput("/usr/bin/top", "-n", "1", "-b")
		fmt.Fprintln(w, outputerr, output)

	case "micadcset":
		adcno, _ := strconv.Atoi(args[1])
		regaddr, _ := strconv.Atoi(args[2])
		regval, _ := strconv.Atoi(args[3])
		fmt.Println("Getval:", adcno, regaddr, regval)

		err := micadc.MicAdcSet(adcno, regaddr, regval)
		fmt.Fprintln(w, adcno, regaddr, regval, err)

	case "uploadlog":
		for i := 0; i < 100; i++ {
			UploadLog(123, 456)
			log.Println(log.DebugLog, "Upload: ", i)
		}

	case "iconmusicmode":
		switch args[1] {
		case "1":
			vui.IconLed_iconMusic001.Show()
		case "2":
			vui.IconLed_iconMusic002.Show()
		case "3":
			vui.IconLed_iconMusic003.Show()
		}
		fmt.Fprintln(w, "Set mode:", args[1])

	case "servicetest":
		globals.Modules[globals.MODULE_PLAYER].ServiceRestart()
		fmt.Fprintln(w, "Restart player!")

	case "voltest":
		ctx, _ := context.WithCancel(context.Background())
		volCtrlTest(ctx)
		fmt.Fprintln(w, "vol test start")
	case "otanighthour":
		begin, _ := strconv.Atoi(args[1])
		end, _ := strconv.Atoi(args[2])
		globals.OTA_BEGIN_HOUR = begin
		globals.OTA_END_HOUR = end
		CrontabInit()
		UpdateCronTime()
		fmt.Fprintln(w, "ota night check:", begin, end)
	case "laoxiao":
		go func() {
			time.Sleep(107 * time.Millisecond)
			nembd.ExecOutput("sh", "/etc/init.d/netease_player_service", "restart")
		}()
		go led_mcu.McuReset()
		fmt.Fprintln(w, "Reset mcu and restart player service!")

	case "mcust": //
		go led_mcu.GetMcuStatus()
		fmt.Fprintln(w, "trig to get mcu status for debug!")

	case "toastnetworkerror":
		ToastNetworkError(false)

	case "copylog":
		CopyLogfiles()
		fmt.Fprintln(w, "Copy log files successfully!")

	case "playad":
		innerTask.ICmdFunc(innerTask.ICmd_Trig_Exec)
		fmt.Fprintf(w, "begin to play ad!")

	case "sendyunxin":
		cmdstring := r.FormValue("cmd")
		cmdint, _ := strconv.Atoi(cmdstring)
		data := r.FormValue("data")
		SendCmdByYunxin(globals.Cmd(cmdint), data, true, "")
		fmt.Fprintln(w, "Send:", cmdstring, data)

	case "adb":
		switch args[1] {
		case "on":
			globals.ADBControl(true)
			fmt.Fprintln(w, "ADB ON!")
		case "off":
			globals.ADBControl(false)
			fmt.Fprintln(w, "ADB OFF!")
		}

	case "mute":
		switch args[1] {
		case "on":
			adau1761.Mute(true)
			fmt.Fprintln(w, "Mute on!")
		case "off":
			adau1761.Mute(false)
			fmt.Fprintln(w, "Mute off!")
		}

	case "bt":
		var btstatus string
		switch args[1] {
		case "on":
			btstatus = "open bt"
			player.OpenBtOfBt()
		default:
			btstatus = "close bt"
			player.CloseBtOfBt()
		}
		fmt.Fprintln(w, btstatus)

	case "forceappota":
		OTACheckNewVersion(true, true)

	case "otacheck":
		OTACheckNewVersion(false, false)

	case "forceota":
		OTACheckNewVersion(true, false)

	case "otanight":
		otaEveryNightCheck()

	case "changeversion":
		if len(args[1]) > 0 {
			globals.GitTag = &args[1]
			fmt.Fprintln(w, "Change version to:", globals.GitTag)
		} else {
			fmt.Fprintln(w, "Change version fail!")
		}

	case "continuesession":
		schedule.SendSCmd(schedule.SCMD_SuperTask_Voice_ContinuSession, VoiceSession_Type(args[1]), args[2])
		fmt.Fprintln(w, "Cotinue session!!")

	case "continueconfirmsession":
		ScheduleNewVoiceSession(VoiceSession_Type_Confirm, "", r.FormValue("data"))
		fmt.Fprintln(w, "Create session!", r.FormValue("data"))

	case "tts":
		schedule.PlayNoticeAsync(globals.AdSrcType_TTS, args[1], globals.CONST_AUDIO_ID, false, nil, nil)
	case "tts2":
		schedule.PlayNoticeAsync(globals.AdSrcType_TTS, r.FormValue("tts"), globals.CONST_AUDIO_ID, false, nil, nil)

	case "msctoast":
		MscToast(globals.AdSrcType_TTS, args[1], globals.CONST_AUDIO_ID, false, false, nil)

	case "mcuota":
		p := r.FormValue("path")
		fmt.Fprintln(w, "Get path:", p)
		if len(p) > 0 {
			led_mcu.McuOtaUpgradeBegin(true, p)
		}
	case "mcuversion":
		fmt.Fprintln(w, "Begin to get version!")
		led_mcu.McuGetVersion()

	case "initmcu":
		led_mcu.InitMcu()
		fmt.Fprintln(w, "Begin to init mcu!")

	case "updateres":
		cvui.UpdateResFromServer()
		fmt.Fprintln(w, "Begin to update resource!")

	case "skin":
		key := args[1]
		value := cvui.GetSkinRes(key)
		fmt.Fprintln(w, key, " = ", value)

	case "directled":
		tp, _ := strconv.Atoi(args[1])
		ac, _ := strconv.Atoi(args[2])
		start, _ := strconv.Atoi(args[3])
		led_mcu.DirectLedControl(atservice.GUIDE_EFFECT_ID(tp), atservice.GUIDE_ACTION(ac), uint8(start), []byte{})
		fmt.Fprintf(w, "Begin show led, effect:%d, action:%d, start:%d\n", tp, ac, start)

	case "enteralarmscene":
		EnterAlarmScene(args[1])
		fmt.Fprintln(w, "Enter scene:", args[1])
	case "vol":
		vol, _ := strconv.Atoi(args[1])
		v, ve := adau1761.SetVol(vol)
		ShowVolumeLed()
		fmt.Fprintln(w, "Set vol:", v, ve)

	case "resetmcu":
		led_mcu.McuReset()
		fmt.Fprintln(w, "Rest mcu finish!")

	case "r16ota":
		md5 := r.FormValue("md5")
		size := r.FormValue("size")
		url := r.FormValue("url")
		DoOtaTest(md5, url, size)
		fmt.Fprintln(w, "md5:", md5, " size:", size, " url:", url)

	case "2versionota":
		md51 := r.FormValue("md51")
		size1 := r.FormValue("size1")
		url1 := r.FormValue("url1")
		version1 := r.FormValue("version1")

		md52 := r.FormValue("md52")
		size2 := r.FormValue("size2")
		url2 := r.FormValue("url2")
		version2 := r.FormValue("version2")

		fmt.Fprintln(w, "md51:", md51, " size1:", size1, " url1:", url1, "version1", version1)
		fmt.Fprintln(w, "md52:", md52, " size:", size2, " url2:", url2, "version2", version2)
		fmt.Fprintln(w, "version:", globals.GitTag)
		if *globals.GitTag != version1 {
			fmt.Fprintln(w, "Upgrade 1!")
			DoOtaTest(md51, url1, size1)
		} else {
			fmt.Fprintln(w, "Upgrade 2!")
			DoOtaTest(md52, url2, size2)
		}

	case "dnslookup":
		maxtimes, _ := strconv.Atoi(args[1])
		delay, _ := strconv.Atoi(args[2])

		fmt.Fprintln(w, "Maxtimes&&delay(ms):", maxtimes, delay)
		go func() {
			errtimes := 0
			for i := 0; i <= maxtimes; i++ {
				ips, err := net.LookupIP(http2.Server)
				if err != nil {
					errtimes++
				}
				log.Println(log.DebugLog, "Cur test domain decocde, curtimes:", i, " errtimes:", errtimes, " domain:", http2.Server, " ip:", ips)
				time.Sleep(time.Duration(delay) * time.Millisecond)
			}
		}()

	case "stressyunxin":
		maxi, _ := strconv.Atoi(args[1])
		buf := make([]byte, 1024*2)
		for k, _ := range buf {
			buf[k] = byte('a')
		}
		for i := 0; i < maxi; i++ {
			SendYunxinNoGuarantee(buf)
			time.Sleep(time.Millisecond * 100)
		}
		fmt.Fprintln(w, "count:", maxi, " finish!")

	case "pressmcu":
		maxi, _ := strconv.Atoi(args[1])
		maxdelay, _ := strconv.Atoi(args[2])
		var costtime time.Duration
		var testtimes int
		fmt.Fprintln(w, "Test times:", maxi, "  Delay(ms):", maxdelay)
		for i := 0; i < maxi; i++ {
			for y := 0; y < globals.MaxVolume; y++ {
				now := time.Now()
				led_mcu.DirectLedControl(atservice.GUIDE_EFFECT_ID_VOLUME_ADJUST, atservice.GUIDE_ACTION_START, 1, []byte{uint8(globals.MaxVolume), uint8(y)})
				costtime = costtime + time.Now().Sub(now)
				testtimes++
				time.Sleep(time.Millisecond * time.Duration(maxdelay))
			}
			fmt.Fprintln(w, "Has tested: ", i+1)
		}
		fmt.Fprintln(w, "Coast time:", costtime, " test times:", testtimes)

	case "continuevoice":
		param := r.FormValue("param")

		vt := VoiceSession_Type(args[1])

		fmt.Fprintln(w, "Continue voice session, ", vt, param)
		ScheduleContinuceSession(vt, param)

	case "enterscene":
		fmt.Fprintln(w, "Enter scene:", args[1])
		schedule.SceneRequestPlay(args[1])

	case "nextscene":
		fmt.Fprintln(w, "Next scene")
		schedule.SceneNextTask()

	case "backupfile2server":
		err := DoBackupFiles2Server(globals.BackupFile_Local)
		fmt.Fprintln(w, "do backupfile:", err)

	case "querybinduser":
		CheckServerBindUser()
		fmt.Fprintln(w, "Check binduser:", globals.BindUser)

	case "showicon":
		var tmp vui.IconLedDesc
		tmp.Name = args[1]
		tmp.Show()
		fmt.Fprintln(w, "Show:", tmp)

	case "icon":
		path := r.FormValue("path")
		fmt.Fprintln(w, "Begin to show icon:", path)
		if len(path) > 0 {
			//log.Println(log.DebugLog, "Show icon path:", path)
			if err, totalFrame, delay, oneImageSize, picData := utils.DecodeImage(path); err == nil {
				fmt.Fprintln(w, "Play simple animamtion totalframe:", totalFrame, " one size:", oneImageSize, " delay:", delay, "size:", len(picData))
				for k, v := range picData {
					//fmt.Printf("%02d  ", v)
					if k%9 == 0 && k != 0 {
						fmt.Fprintf(w, "\n")
					}
					if k%81 == 0 && k != 0 {
						fmt.Fprintf(w, "\n\n")
					}
					if false {
						if v > 0 {
							fmt.Fprintf(w, " # ")
						} else {
							fmt.Fprintf(w, " @ ")
						}
					} else {
						fmt.Fprintf(w, " %02x", v)
					}

				}
				led_mcu.PlaySimpleAnimation(uint8(0), uint8(totalFrame), uint16(oneImageSize), uint16(delay), picData)
			} else {
				fmt.Fprintln(w, "Decode image err:", err)
			}
		} else {
			fmt.Fprintln(w, "Path is null!")
		}

	case "backupfiles":
		DoBackupFileToLocal()

	case "restorefiles":
		DoRestoreFileToLocal()

	case "encodefile":
		ioutil.WriteFile("/tmp/aa.txt", []byte("Hello Ihw!"), os.ModePerm)
		utils.EncryptFile("/tmp/aa.txt", "/tmp/aa_encode.txt", []byte("ihw123456"))
		fmt.Fprintln(w, "source: /tmp/aa.txt dest: /tmp/aa_encode.txt")
		data, _ := ioutil.ReadFile("/tmp/aa_encode.txt")
		fmt.Fprintln(w, string(data))
	case "decodefile":
		utils.DecryptFile("/tmp/aa_encode.txt", "/tmp/aa_decode.txt", []byte("ihw123456"))
		fmt.Fprintln(w, "dest:/tmp/aa_decode.txt  source:/tmp/aa_encode.txt")
		data, _ := ioutil.ReadFile("/tmp/aa_decode.txt")
		fmt.Fprintln(w, string(data))

	case "execcmd":
		if len(args) > 2 {
			out, outerr := nembd.ExecOutput(args[1], args[2:]...)
			fmt.Fprintln(w, out, outerr)
		} else {
			out, outerr := nembd.ExecOutput(args[0])
			fmt.Fprintln(w, out, outerr)
		}

	case "execstartupsh":
		cont, err := AfterStarupConnectInternet()
		fmt.Fprintln(w, "Exec starup exec finish:", cont, err)

	case "psutil":
		vm, err := mem.VirtualMemory()
		fmt.Fprintf(w, "err:%+v, \n Getinto:%+v\n", err, vm)
		if pcent, err := cpu.Percent(0, false); err == nil {
			fmt.Fprintf(w, "cpu:%+v\n", pcent)
		}
		if cpuinfo, err := cpu.InfoWithContext(context.Background()); err == nil {
			fmt.Fprintf(w, "cpuinfo:%+v\n", cpuinfo)
		}

		if avg, err := load.Avg(); err == nil {
			fmt.Fprintf(w, "load:%+v\n", avg)
		}
		if boottime, err := host.BootTime(); err == nil {
			fmt.Fprintf(w, "Boot time:%+v\n", boottime)
		}
		if uptime, err := host.Uptime(); err == nil {
			fmt.Fprintf(w, "Boot time:%+v\n", uptime)
		}

		if infodata, err := host.Info(); err == nil {
			fmt.Fprintf(w, "Info stat:%+v\n", *infodata)
		}

		if alp, err := process.Processes(); err == nil {
			for _, v := range alp {
				fmt.Fprintf(w, " Pid:%+v", v.Pid)
				if v, err := v.CPUPercent(); err == nil {
					fmt.Fprintf(w, " Cpu percent:%+v", v)
				}

				if v, err := v.CreateTime(); err == nil {
					fmt.Fprintf(w, " Create time:%+v", v)
				}

				if v, err := v.MemoryInfo(); err == nil {
					fmt.Fprintf(w, " mem:%+v", *v)
				}

				if v, err := v.MemoryInfoEx(); err == nil {
					fmt.Fprintf(w, " mem ext:%+v", v)
				}

				if v, err := v.MemoryPercent(); err == nil {
					fmt.Fprintf(w, " Mem percent:%+v", v)
				}

				if v, err := v.Name(); err == nil {
					fmt.Fprintf(w, " Name:%+v", v)
				}

				if v, err := v.NumFDs(); err == nil {
					fmt.Fprintf(w, " Fd num:%+v", v)
				}

				if v, err := v.NumThreads(); err == nil {
					fmt.Fprintf(w, " Num thread:%+v", v)
				}

				if v, err := v.Status(); err == nil {
					fmt.Fprintf(w, " Status:%+v", v)
				}

				fmt.Fprintf(w, "\n")
			}
		}

	default:
		fmt.Fprintln(w, "Unknow key:", args[0])
	}

	fmt.Fprintln(w, "Finish execing!!")
}

func InitHttpServer() {
	user := "gordon"
	pass := "secret!"

	router := httprouter.New()
	router.POST("/wificonfig", HTTPSERVER_WifiConfig)
	router.POST("/connect", HTTPSERVER_Connect)
	router.GET("/protected/", BasicAuth(Protected, user, pass))
	router.GET("/httpenv/:mode", HTTPSERVER_HttpEnv)
	router.GET("/pvt/schedule/status", HTTPSERVER_ScheduleStatus)
	router.GET("/pvt/test/*args", HTTPSERVER_test)
	router.GET("/pvt/json/:args", HTTPSERVER_JSON)

	router.HandlerFunc("GET", "/debug/pprof/*filepath", http.HandlerFunc(pprof.Index))
	router.HandlerFunc("GET", "/debug/pprof2/cmdline", http.HandlerFunc(pprof.Cmdline))
	router.HandlerFunc("GET", "/debug/pprof2/profile", http.HandlerFunc(pprof.Profile))
	router.HandlerFunc("GET", "/debug/pprof2/symbol", http.HandlerFunc(pprof.Symbol))
	router.HandlerFunc("GET", "/debug/pprof2/trace", http.HandlerFunc(pprof.Trace))
	router.Handler("GET", "/ihw/debug/vars", http.Handler(expvar.Handler()))

	LogFiles(router, "/pvt/logfile/*filepath", http.Dir("/tmp"))
	//router.ServeFiles("/logfile/*filepath", http.Dir("/tmp/glog"))

	go http.ListenAndServe(":1705", router)
	runtime_metrics.Run_go_runtime_metrics()
	log.Println(log.DebugLog, "Http server started!")
}
