package main

import (
	"fmt"
	"net/http"

	jwt "github.com/dgrijalva/jwt-go"
	"github.com/dgrijalva/jwt-go/request"
	"github.com/go-martini/martini"
)

func ValidateTokenMiddleware(w http.ResponseWriter, r *http.Request, c martini.Context) {

	token, err := request.ParseFromRequest(r, request.AuthorizationHeaderExtractor,
		func(token *jwt.Token) (interface{}, error) {
			return []byte(SignedString), nil
		})
	if err == nil {
		if token.Valid {
			c.Next()
		} else {
			w.WriteHeader(http.StatusUnauthorized)
			fmt.Fprint(w, "Token is not valid")
		}
	} else {
		w.WriteHeader(http.StatusUnauthorized)
		fmt.Fprint(w, fmt.Sprintf("Unauthorized access to this resource:%s", err.Error()))
	}
}

// martini router
func route(m *martini.ClassicMartini) {
	m.Group("/application/v1", func(r martini.Router) {
		// find a device by key
		r.Get("/device/info", ApplicationAuthOnDeviceIdentifer, GetDeviceInfoByKey)

		// find a device by identifier
		r.Get("/devices/:identifier/info", ApplicationAuthOnDeviceIdentifer, GetDeviceInfoByIdentifier)

		// get devie current status
		r.Get("/devices/:identifier/status/current",
			ApplicationAuthOnDeviceIdentifer, CheckDeviceOnline, CheckProductConfig,
			GetDeviceCurrentStatus)

		// get device status by specific fields
		r.Get("/devices/:identifier/status/fields",
			ApplicationAuthOnDeviceIdentifer, CheckDeviceOnline, CheckProductConfig,
			GetDeviceStatusByFields)

		// get devie latest status
		r.Get("/devices/:identifier/status/latest",
			ApplicationAuthOnDeviceIdentifer, CheckDeviceOnline, CheckProductConfig,
			GetDeviceLatestStatus)

		// set device status
		r.Put("/devices/:identifier/status",
			ApplicationAuthOnDeviceIdentifer, CheckDeviceOnline, CheckProductConfig,
			SetDeviceStatus)

		r.Post("/devices/:identifier/ota", ApplicationAuthOnDeviceIdentifer, CheckDeviceOnline, DeviceUpgrade)

		// send a command to device
		r.Post("/devices/:identifier/commands",
			ApplicationAuthOnDeviceIdentifer, CheckDeviceOnline, CheckProductConfig,
			SendCommandToDevice)

		// and a rule to device
		r.Post("/devices/:identifier/rules",
			ApplicationAuthOnDeviceIdentifer, CheckDeviceIdentifier,
			AddRule)
		r.Get("/devices/check_net_config", ApplicationAuthOnDeviceIdentifer, CheckDeviceNetConfig)

		r.Get("/devices/online", CheckDeviceIsOnline)

		r.Post("/scene_task", SubmitSceneTask)

		r.Post("/task_lifecycle", SubmitTaskLifecycle)

		r.Post("/submit_scene", SubmitSceneAction)

		// 设备指令查询
		r.Get("/device_commands", ApplicationAuth, GetDeviceCommands)

		// 设备状态查询
		r.Get("/device_status_list", ApplicationAuth, GetDeviceStatusList)

		// 场景执行历史查询
		r.Get("/scene_his", ApplicationAuth, GetSceneHis)
		r.Get("/scene_his/:scene_id", ApplicationAuth, GetSceneHisBySceneId)
	})
	m.Group("/application/v2", func(r martini.Router) {
		// send a command to device
		r.Post("/devices/:identifier/commands",
			ApplicationAuthOnDeviceIdentifer, CheckDeviceOnline, CheckProductConfig,
			SendCommandToDeviceV2)
	})

	m.Post("/application/auth", AppAuth)

}
